如何为Delphi / Free Pascal / Lazarus DLL创建C-Header - 数据类型

时间:2013-09-11 06:29:02

标签: c delphi dll header-files stdcall

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

1 个答案:

答案 0 :(得分: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}