【问题标题】:delphi records and c structsdelphi 记录和 c 结构
【发布时间】:2009-12-07 01:25:42
【问题描述】:

任务:

用 Delphi 编写的应用程序接受三个字段的结构(在 Delphi 中为record)。我可以使用SendMessage(Win32 API)函数发送这个结构的指针。

所以一个问题是:

Delphi如何在内存中维护一定的结构表示?

有类型

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

如何在 C 中定义它?我的意思是,Delphi 结构中是否有任何隐藏或服务字段?

【问题讨论】:

  • 一个警告:取决于所使用的 Delphi 版本(= 2009)PChar 被定义为 PAnsiChar 或 PWideChar。更好:使用指针类型 PAnsiChar / PWideChar 之一指定要使用的类型或字符。

标签: c delphi struct record


【解决方案1】:

不,没有隐藏字段,Delphi 记录和 C 结构可以 1:1 相互映射,但有一些注意事项:

  • 不要使用任何数据类型 C 没有 理解。这包括对象, 动态数组和 Delphi 字符串。

  • C 和 Delphi 有时有不同的 关于如何对字段进行字节对齐的想法。 测试您的记录并验证 他们在C端工作。如果他们 不要,尝试使用打包记录 而不是记录

  • 将指针传递给记录时 从 C 到 Delphi,反之亦然,使 确保接收它的一方 不会尝试释放或重新分配 记忆。它属于记忆 创建它的经理。

【讨论】:

  • 谢谢。大约第 2 点。是否可以在c中使用类似于打包记录(未打包记录)的东西。 Delphi 应用程序应该关闭以进行编辑甚至查看。
  • 我不确定您在 C 中的结构打包选项是什么。请尝试检查您的编译器文档。
  • Delphi 编译器和 C 编译器都有关于如何对齐记录/结构中的数据字段的各种选项和编译指示,因此通常为了互操作性,它在代码中显式添加(作为C 代码中的 pragma 和 Delphi 中的打包记录。如果不是,它总是在猜测正在使用什么对齐规则。
【解决方案2】:

请注意,虽然您当然可以将这种结构的地址发送到另一个应用程序,例如 SendMessage() 调用中的 LPARAM,但它很可能不起作用。原因是同一个指针在另一个拥有自己地址范围的应用程序中使用时,通常不会指向同一个物理内存位置。

它适用于像WM_GETTEXT这样的一些Windows消息,在这些情况下,操作系统会在幕后进行必要的映射,以便接收应用程序可以将数据复制到调用应用程序分配的缓冲区,并且地址指向到两个应用程序中的同一块物理内存。

同样可以通过使用WM_COPYDATA 消息来实现,该消息旨在在两个应用程序之间进行数据交换时进行必要的内存编组。

但是您问题中的结构还有另一个问题,因为它包含指向内存的指针。 WM_COPYDATA 文档明确指出不能这样做。虽然整个内存块的地址将被修改为在接收应用程序中有效,但系统无法知道内存块的哪些部分是指针并且也需要映射。因此,所有包含的指针都将保持原样并且可能无效。您的单链表将被破坏,PChar 元素也将无法访问。

编辑:

关于您的 cmets:仅当您尝试从其他应用程序发送消息时,以上几点才重要;如果您从 DLL 执行此操作,则一切正常,因为 DLL 共享它被加载到的进程的地址空间,因此应用程序中使用的指针或任何加载的 DLL 将始终指向相同的内存位置。对于这可能造成的任何混乱,我们深表歉意,但从您的问题来看,数据交换发生在一个应用程序内对我来说并不明显。

【讨论】:

  • 类似的程序可以工作,如果用 Delphi 编写的话。在编译我的 C 应用程序(在 DLL 中)时,我可能会使用任何内存管理限制标志吗?正如我在帖子中所写的那样,Delphi App 的源代码甚至无法查看。
  • 哦,顺便说一句。当从目标应用程序加载的 DLL 调用函数时,您所写的关于不同内存分配的内容是否正确?
  • 无论如何你的信息很有用。非常感谢您指出问题。
猜你喜欢
  • 2012-07-28
  • 2012-02-20
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-09-04
  • 1970-01-01
相关资源
最近更新 更多