Вопрос

Задача:

Приложение, написанное на 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, всегда будет указывать на одну и ту же ячейку памяти.Извините за путаницу, которую это могло вызвать, но из вашего вопроса для меня не было очевидно, что обмен данными происходит внутри одного приложения.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top