views:

318

answers:

2

Task: Application written in Delphi accepts a structure (record in terms of Delphi) of three fields. I can send the pointer of this structure using SendMessage (Win32api) function.

So a question is: How to maintain certain structure representation in memory for delphi in terms of delphi. It has type

    PWPModPostData = ^ TWPModPostData;
    TWPModPostData = record
       DataType: Integer;
       Data: PChar;
       Next: PWPModPostData;
    end;

How to define it in C. I mean, is there any hidden or service fields in Delphi structures?

+6  A: 

No, there are no hidden fields, and Delphi records and C structs can be mapped to each other 1:1, with a few caveats:

  • Don't use any data type C doesn't understand. This includes objects, dynamic arrays, and Delphi strings.

  • C and Delphi sometimes have different ideas about how to byte-align fields. Test your records and verify that they work on the C side. If they don't, try using packed record instead of record.

  • When passing a pointer to a record from C to Delphi or vice versa, make sure that the side receiving it doesn't try to free or reallocate the memory. It belongs to the memory manager that created it.

Mason Wheeler
Thank you. about 2nd point. Is it possible to use something similar to packed record (unpacked record) in c. Delphi Application is supposed to be closed for editing and even viewing.
Vasiliy Stavenko
I'm not sure what your struct-packing options are in C. Try checking your compilerr documentation.
Mason Wheeler
Both the Delphi compiler and C compiler(s) have all kind of options and pragma's on how data fields in records/stucts are aligned, So usually for interoperability, it is added explicitly in code (as a pragma in C code and as a packed record in Delphi. If not, It is always guessing what alignment rules are being used.
Ritsaert Hornstra
+4  A: 

Note that while you can certainly send the address of such a structure to another application as the LPARAM of a SendMessage() call it will most probably not work. The reason is that the same pointer will usually not point to the same physical memory location when used in another application with its own address range.

It works for a few Windows messages like WM_GETTEXT, and in these cases the OS does the necessary mapping behind the curtain, so that the receiving application can copy data to the buffer allocated by the calling application, and the address points to the same chunk of physical memory in both applications.

The same can be achieved by using the WM_COPYDATA message, which is intended to do the necessary marshalling of memory when doing data exchange between two applications.

But the structure in your question has another problem, because it contains pointers to memory. The WM_COPYDATA documentation explicitly states that this must not be done. While the address of the whole memory block will be modified to be valid in the receiving application the system can not know which parts of the memory block are pointers and would need to be mapped as well. All contained pointers will therefore be left as-is and be likely invalid. Your singly-linked list will be broken, and the PChar elements won't be accessible either.

Edit:

Regarding your comments: Above points are important only if you attempt to send messages from other applications; if you do this from a DLL things will work, because a DLL shares the address space of the process it was loaded into, so a pointer used in the application or any loaded DLL will always point to the same memory location. Sorry for any confusion this might have caused, but it wasn't obvious to me from your question that the data exchange happens inside one application.

mghie
Similar program works, if written in Delphi. Is there any Memory management restriction flags which I probably may use while compiling my C application(which is in DLL)? As I wrote in post higher Delphi App's source is unavailable even for viewing.
Vasiliy Stavenko
Oh by the way. Is that what you has written about different memory allocations correct, when calling funcs from DLL, which loaded by target application?
Vasiliy Stavenko
Anyway your info is useful. Thanks much for pointing on issue.
Vasiliy Stavenko