записи Delphi и структуры C
Вопрос
Задача:
Приложение, написанное на Delphi, принимает структуру (record
в терминах Delphi) трех полей.Я могу отправить указатель на эту структуру, используя SendMessage
(Win32 API).
Итак, вопрос:
Как сохранить определенное представление структуры в памяти для Delphi с точки зрения Delphi?
Он имеет тип
PWPModPostData = ^ TWPModPostData;
TWPModPostData = record
DataType: Integer;
Data: PChar;
Next: PWPModPostData;
end;
Как это определить в C?Я имею в виду, есть ли в структурах Delphi какие-либо скрытые или служебные поля?
Решение
Нет, скрытых полей нет, а записи Delphi и структуры C можно сопоставить друг с другом 1:1, с некоторыми оговорками:
Не используйте тип данных C не понимает.Это включает в себя объекты, динамические массивы и струны Delphi.
C и Delphi иногда имеют разные идеи о том, как поля Byte-Alight.Проверьте свои записи и убедитесь, что они работают на стороне C.Если они этого не делают, попробуйте использовать упакованная пластинкавместо записывать.
При прохождении указателя на запись от C в Delphi или наоборот, убедитесь, что сторона, получающая ее, не пытается освободить или перераспределять память.Он принадлежит менеджеру памяти, который создал ее.
Другие советы
Обратите внимание: хотя вы, безусловно, можете отправить адрес такой структуры в другое приложение, например LPARAM
из SendMessage()
позвонить, скорее всего, не получится.Причина в том, что один и тот же указатель обычно не будет указывать на одну и ту же ячейку физической памяти при использовании в другом приложении с собственным диапазоном адресов.
Это работает для нескольких сообщений Windows, таких как WM_GETTEXT
, и в этих случаях ОС выполняет необходимое сопоставление за кулисами, чтобы принимающее приложение могло копировать данные в буфер, выделенный вызывающим приложением, а адрес указывал на один и тот же фрагмент физической памяти в обоих приложениях.
Того же самого можно добиться, используя WM_COPYDATA
сообщение, которое предназначено для необходимой сортировки памяти при обмене данными между двумя приложениями.
Но у структуры в вашем вопросе есть еще одна проблема, поскольку она содержит указатели на память.А WM_COPYDATA
в документации прямо указано, что этого делать нельзя.Хотя адрес всего блока памяти будет изменен, чтобы быть действительным в принимающем приложении, система не может знать, какие части блока памяти являются указателями, и их также необходимо будет отобразить.Поэтому все содержащиеся указатели останутся как есть и, скорее всего, станут недействительными.Ваш односвязный список будет нарушен, и PChar
элементы также не будут доступны.
Редактировать:
Что касается ваших комментариев:Вышеуказанные пункты важны только в том случае, если вы пытаетесь отправлять сообщения из других приложений;если вы сделаете это из DLL, все будет работать, потому что DLL разделяет адресное пространство процесса, в который она была загружена, поэтому указатель, используемый в приложении или любой загруженной DLL, всегда будет указывать на одну и ту же ячейку памяти.Извините за путаницу, которую это могло вызвать, но из вашего вопроса для меня не было очевидно, что обмен данными происходит внутри одного приложения.