Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Win32/Win64 API (native code) (https://www.delphipraxis.net/17-win32-win64-api-native-code/)
-   -   [gelöst] Probleme mit CopyMemory (https://www.delphipraxis.net/159188-%5Bgeloest%5D-probleme-mit-copymemory.html)

WM_CLOSE 17. Mär 2011 14:19


[gelöst] Probleme mit CopyMemory
 
Guten Tag,
Ich habe hier folgendes Problem:
Ich würde gerne per WM_COPYDATA einen record an eine Applikation senden. leider macht mit CopyMemory Probleme:

Delphi-Quellcode:
function TMyObject<T>.SendRec(Rec:T):Boolean;
var
  CopyData:TCopyDataStruct;
  SendRecord:^T;
  Size:Cardinal;
begin
  New(SendRecord);
  try
    Size:=SizeOf(T);
    CopyMemory(SendRecord, @rec, SizeOf(T));  <--fürt zu einem fehler

 //ab hier ist eig alles unwichtig
 //   CopyData.cbData := SizeOf(T);
 //   CopyData.lpData := SendRecord;
 //   ...
  finally
    Dispose(SendRecord);
  end;
end;
Die EAccessiViolation tritt aber erst beim Beenden des Programms auf.

Der Record besteht aus:
Delphi-Quellcode:
type
  TMyRecord=packed record
    Var1:Cardinal;
    Var2:Cardinal;
    Test:Array[1..30]of Char;
  end;
So wird die SendRec-Methode aufgerufen:
Delphi-Quellcode:
var
  rec:TTranscieverRecord;
begin
  rec.Var1 := StrToIntDef(Edit1.Text, 0);
  rec.Var2 := StrToIntDef(Edit2.Text, 0);
  FillChar(rec.Test, SizeOf(rec.Test), #0);
  StrCopy(@(rec.Passwort[1]), PChar(Edit3.Text));
  ...
Weiß jemand eine Lösung?
Danke

Neutral General 17. Mär 2011 14:29

AW: Probleme mit CopyMemory
 
Hallo,

Habe das mal probiert:

Delphi-Quellcode:
type
  TMyRecord=packed record
    Var1:Cardinal;
    Var2:Cardinal;
    Test:Array[0..30] of Char;
  end;
  PMyRecord = ^TMyRecord;
Programm1 (Sender):
Delphi-Quellcode:
procedure TForm1.SendRec<T>(AHandle: THandle; Rec: T);
var
  CopyData: TCopyDataStruct;
  SendRecord: ^T;
  Size: Cardinal;
begin
  New(SendRecord);
  try
    // CopyMemory(SendRecord, @rec, SizeOf(T));
    // Oder, wie Himitsu schon vorgeschlagen hat (schöner):
    SendRecord^ := rec;

    CopyData.cbData := SizeOf(T);
    CopyData.lpData := SendRecord;
    CopyData.dwData := Cardinal(SendRecord);

    SendMessage(AHandle,WM_COPYDATA,Handle,LParam(@CopyData));
  finally
    Dispose(SendRecord);
  end;
end;

procedure TForm1.Button1Click(Sender: TObject);
var test: TMyRecord;
begin
  test.Var1 := 1234;
  test.Var2 := 9876;
  test.Test := 'Hallo Welt!';
  SendRec<TMyRecord>(FindWindow(nil,'Form2'),test);
end;

Programm 2 (Empfänger):
Delphi-Quellcode:
// ...
public
  procedure Data(var Msg: TWMCopyData); message WM_COPYDATA;
end;
// ...

procedure TForm2.Data(var Msg: TWMCopyData);
var tmp: TMyRecord;
begin
  tmp := PMyRecord(Msg.CopyDataStruct^.lpData)^;
  Showmessage(Format('Var1: %d, Var2: %d, Test: %s',[tmp.Var1,tmp.Var2,tmp.Test]));
end;
Bei mir funktioniert das ohne Probleme!

himitsu 17. Mär 2011 14:45

AW: Probleme mit CopyMemory
 
Delphi-Quellcode:
// statt

Size:=SizeOf(T);
CopyMemory(SendRecord, @rec, SizeOf(T)); <--fürt zu einem fehler

// dieses

T^ := Rec;

WM_CLOSE 18. Mär 2011 06:41

AW: Probleme mit CopyMemory
 
Ok, Ich habe jetzt statt dem Pointer
Delphi-Quellcode:
SendRecord: ^T;
eine Variable des Typs T benutzt:
Delphi-Quellcode:
SendRecord: T;
Dann geht es. Scheint ein Problem des Speichermanagers im Zusammenhang mit den Generics zu sein.:(

Danke euch beiden
:):-D:):-D:)

himitsu 18. Mär 2011 06:46

AW: Probleme mit CopyMemory
 
Ja, die Generics haben so ihre Macken.
Selbst ein SizeOf(T) geht nicht immer. :wall:

Nja, ohne das New, Try-Finally und Dispose wird der Code sowieso etwas übersichtlicher, wenn man nun einfach die automatische Speicherverwaltung nutzt. :angle:


Alle Zeitangaben in WEZ +1. Es ist jetzt 17:51 Uhr.

Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz