![]() |
Daten von C# an Delphi senden
Moin,
Von einer C#-Applikation soll mittels WM_COPYDATA Daten an eine Delphi Anwendung geschickt werden. WMCOPYDATA kommt in der Delphi Anwendung schon mal an, doch werden die Werte nicht übermittelt. Sehr wahrscheinlich liegt es am Delphi TMyStruct Record, welcher zum c# struct nicht kompatibel ist. Vielen Dank im Voraus für eure Hilfe. Sender:
Code:
Empfänger:
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
internal struct MyStruct { public int Number; [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 256)] public string Message; } // ..... myStruct.Number = 1234; myStruct.Message = "hello"; int myStructSize = Marshal.SizeOf(myStruct); IntPtr pMyStruct = Marshal.AllocHGlobal(myStructSize); try { Marshal.StructureToPtr(myStruct, pMyStruct, true); COPYDATASTRUCT cds = new COPYDATASTRUCT(); cds.cbData = myStructSize; cds.lpData = pMyStruct; NativeMethod.SendMessage(hTargetWnd, WM_COPYDATA, NativeMethod.GetForegroundWindow(), ref cds); }
Delphi-Quellcode:
type
TMyStruct = packed record Number: integer; Msg: string[255]; end; PMyStruct = ^TMyStruct; procedure TfrmHelper.WMCOPYDATA(var msg: TWMCopyData); var MyRecord: PMyStruct; s: String[255]; Number: integer; begin s := PMyStruct(msg.CopyDataStruct.lpData)^.Msg; Number := PMyStruct(msg.CopyDataStruct.lpData)^.Number; ShowMessage('Msg ' + s + ' Number: ' + IntToStr(Number)); end; |
AW: Daten von C# an Delphi senden
Die Kernfrage ist, wie man diese beiden Konstrukte zueinander kompatibel macht:
Delphi-Quellcode:
type
TMyStruct = packed record Number: integer; Msg: string[255]; end; PMyStruct = ^TMyStruct;
Code:
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
internal struct MyStruct { public int Number; [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 256)] public string Message; } |
AW: Daten von C# an Delphi senden
Was kommt denn an? Siehst Du die 1234 oder nur Murks? Aber ... vielleicht solltest Du den String noch als WideString deklarieren (sowohl in Delphi, als auch in C# das Attribut).
|
AW: Daten von C# an Delphi senden
Welche Delphi Version?
String kann ein ANSI String sein (vor Delphi 2009) oder ein UNICODE String (ab Delphi 2009). PChar belegt ein byte, PWideChar 2 byte. Folglich sind dann auch die Records unterschiedlich groß; prüf das doch mal. Grüße! |
AW: Daten von C# an Delphi senden
1. Im C#-Code steht 'UniCode' ;-) und danach muss sich (am besten explizit) alles richten, d.h. gar nicht auf die Delphi-Version setzen.
2. Kommt '1234' wenigstens an zielte darauf, die grundsätzliche Korrektheit der Übertragung sicherzustellen und den Fehler auf die Stringdeklaration(en) einzugrenzen. |
AW: Daten von C# an Delphi senden
Zitat:
|
AW: Daten von C# an Delphi senden
Die Nachricht kommt grundsätzlich beim Empfänger an. Entferne ich den String aus dem struct resp. Record, kommt auch der Integer Wert korrekt an.
Das Problem verursacht also definitiv der String. Werde es mal mit einem array[0..255] of WideChar versuchen (Delphi Version: XE4) |
AW: Daten von C# an Delphi senden
Ist dieses
Delphi-Quellcode:
eigentlich ein CharArray (ala ShortString), oder ist das ein Pointer/Objekt?
public string Message;
Außerdem ist das im C# gaantiert kein ShortString, denn als alter Pascal-Typ ist der ShortString intern so aufgebaut:
Delphi-Quellcode:
bzw. eigentlich
type
String[X] = packed record Length: Byte; Chars: array[1..X] of AnsiChar; end; ShortString = String[255];
Delphi-Quellcode:
Wobei die Position 0 das Längen-Byte ist, weswegen Pascal-Strings auch mit 1 beginnen/begannen.
type
String[X]: array[0..X] of AnsiChar; LongString's (String, AnsiString/UTF8String/RawByteString und UnicodeString) sind dagegen nochmal anders aufgebaut ... die sind praktisch ein aufgemotztes dynamisches Char-Array. Und der WideString ist nochmal was Anderes. (Kapselung einer WinAPI) Und zusätlich kann man alle Zeigertypen für Strings beim WM_COPYDATA vergessen. Wobei es hier bestimmt bessere Varianten der IPC geben würde, welche auf beiden Seiten nativ unterstützt werden. (Pipes, Sockets, MMFs, ...) |
AW: Daten von C# an Delphi senden
Hmm.. weis jetzt nicht wo das Problem liegt.. und ja ich sende strings
Ich hab da kein Problem allerdings in umgekehrter Reihenfolge. (Delphi nach C#)
Delphi-Quellcode:
// added song to Playlist
for i := 0 to fAlbumList.Count - 1 do WAAddFile(Module^.hWNDParent, AnsiString(fFilePath + fAlbumList.Strings[i]));
Delphi-Quellcode:
Ausgewertet in C#
function int_cds(mainwawnd: HWND; text: AnsiString; msg: Integer): Integer;
var cds: COPYDATASTRUCT; begin cds.dwData := msg; cds.lpData := PAnsiChar(text); cds.cbData := (lstrlen(cds.lpData)+1) * SizeOf(Char); {include space for null char} result := SendMessage(mainwawnd, WM_COPYDATA, 0, LPARAM(@cds)); end; function WAAddFile(mainwawnd: HWND; FilePath: AnsiString): Integer; begin result := int_cds(mainwawnd, FilePath, IPC_PLAYFILE); end;
Code:
public struct COPYDATASTRUCT { public IntPtr dwData; public int cbData; [MarshalAs(UnmanagedType.LPStr)] public string lpData; }
Code:
case BASSVIS_PLAYSTATE.AddPlaylistTitle: COPYDATASTRUCT cds = new COPYDATASTRUCT(); cds = (COPYDATASTRUCT)Marshal.PtrToStructure((IntPtr)BassVis.BASSVIS_SetPlayState(mVisParam, BASSVIS_PLAYSTATE.AddPlaylistTitle), typeof(COPYDATASTRUCT)); Title = cds.lpData; lstPathList.Items.Add(Title); Playlist.Items.Add(Path.GetFileNameWithoutExtension(Title)); break; Es wird also die Playliste gelöscht und mit
Delphi-Quellcode:
SendMessage(mainwawnd, WM_COPYDATA, 0, LPARAM(@cds));
in der C# Anwendung neu gefüllt. Das ganze geht dann über zwei Delphi-DLL's in die Anwendung. (GLPlugin, PluginWrapper, C# Anwendung) Vielleicht hilft es dir ja. Nebenbei: Ist die Struct in C# überhaupt ein Packed Record? (Dadurch addierst du ein Byte zum Record) Denke mal nicht. gruss |
AW: Daten von C# an Delphi senden
Zitat:
Es wird nur der Daten-Record übertragen, aber ob da Zeiger drin sind, ist dem Ding total egal und es ignoriert Diese. |
Alle Zeitangaben in WEZ +1. Es ist jetzt 07:46 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz