【问题标题】:Howto create C-Header for Delphi/Free Pascal/Lazarus DLL - data types如何为 Delphi/Free Pascal/Lazarus DLL 创建 C-Header - 数据类型
【发布时间】:2013-09-11 06:29:02
【问题描述】:

对于我的应用程序,我需要使用 stdcall 从 Delphi 创建一个 DLL(更准确地说是在 Lazarus IDE 中编写的由 Linux 下的 free pascal 编译的 Delphi 兼容代码)。
在使用该 DLL 时(例如在 Matlab 中),当然需要元信息来传递参数 - 通常通过头文件实现。 我正在寻找一种在delphi源代码上运行的工具。类似h2pas-reverse。
我的研究没有结果。我想,没有这样的工具,我想找一个表或其他信息,Delphi/Pascal 数据类型如何映射到 C 类型以及如何处理记录。

【问题讨论】:

  • Integer -- int, Double -- double, Single -- float, Byte -- char, record -- 结构。你想要更多吗?
  • 感谢@DavidHeffernan - 这对于一开始来说非常酷。有时我需要 Cardinal - 这是否映射到 unsigned long?
  • 没有。它是无符号整数。
  • 如果您在 Linux 上,您的 long 将是 64 位,对吗?小心点。

标签: c delphi dll header-files stdcall


【解决方案1】:

当 Delphi 有 -JPH 开关时,我使用以下构造从 Delphi 5 代码生成与 Visual C++ 6 的 C 模式编译器兼容的头文件(请参阅下面的注释)。

请注意,我从 Delphi 5 开始就没有使用过这个,但是从那以后这个开关已经被扩展了:

在某处,JPHNE switch 已添加到dcc32 命令行编译器:

  -JPHNE = Generate C++ .obj file, .hpp file, in namespace, export all

Rudy Velthuis 有一个nice article using the JPHNE switch

它当然不能处理所有类型,您将需要相当多的 HPPEMITEXTERNALSYM 指令。

我将我的Delphi 5 to Visual C++ 6 HPP conversion from back then 上传到 BitBucket。

它会生成 .hpp 文件以导入用 Delphi 编写的 DLL。

Delphi 5 时代的笔记:

{ Visual C++ 6 does not like nested structs/unions the way that BC++ can handle them.
  Visual C++ 6 requires the "typedef" to be present AND the typename AFTER the struct definition.
  You will see this when defining TConversationId, TReturnKey and other types that depend on nested structs/unions

  The trick is to perform these steps each and every time this unit changes:
    - Generate this unit once with all the EXTERNALSYM disabled.
      - Then the DCC32 -JPH will generate the basic structs for them.
    - Copy all the nested struct and union definitions to this file
    - Embed the definitions with (*$HPPEMIT '' *)
    - Append the typename at the end of the struct definition
    - Enable all the EXTERNALSYM again
    - Regenerate the HPP files by using DCC32 -JPH
  To make this process easier, we have introduced two new conditional defines:
    - BCB - disable EXTERNALSYM, disable HPPEMIT
    - VC6 - enable EXTERNALSYM, enable HPPEMIT

  A similar thing is with these constructions that VC6 does not like those either:
    - short strings (BCB defines them as "SmallString<##>" which VC6 does not like).
    - short integers (BCB defines them as "Shortint" so we have included an HPPEMIT for that)
}

{$ifdef win32}
  { important! Makes sure that the all enumerated types fit in exactly one byte each! }
  {$Z1}

  { force the C/C++ HPP header files to have the C/C++ compiler pack structure elements on byte boundaries }
  {$ifdef BCB}
    {$HPPEMIT '#pragma option push -a1' }
  {$endif BCB}
{$endif win32}

【讨论】:

  • DLL 是用 FreePascal 编写的,而不是 Delphi。 FreePascal 不支持 C++,AFAIK 没有与 Delphi 的 C++ 输出开关等效的功能。
  • @RemyLebeau .hpp 文件与 Visual C++ 6 编译器的 C 模式兼容,只是它们生成为 .hpp 文件,而不是 .h 文件。即使 FreePascal 工具不允许此类导出,鉴于代码与 Delphi 兼容,这也是 Bastian 可以使用的途径。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2012-12-19
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-05-03
  • 1970-01-01
相关资源
最近更新 更多