【问题标题】:Can I use C headers in Delphi?我可以在 Delphi 中使用 C 头文件吗?
【发布时间】:2011-06-04 14:46:01
【问题描述】:

是否可以使用 Rad Studio XE C++ 编译器编译 C 头文件并将它们与 Delphi 代码链接?

这样就不需要将头文件转换成pascal了?

问题的原因是..

C - 标题定义:

DLLEXPORT int url_engine_version(char *version, size_t length);

尝试德尔福定义

function url_engine_version(version: PByte; var length: cardinal): integer;
  cdecl; external 'corplib.dll';

主应用程序尝试使用以下方法调用它:

engVer: Pointer;
engLen: cardinal;

engLen := 64;
GetMem(engVer,engLen);
url_engine_version(engVer,engLen);

但 Delphi AV 在尝试调用例程时。

有效的 C# 定义 - 如果我传递一个预先定义为长度 64 的 StringBuilder,Chick 就可以工作

[DllImport("corplib.dll", CharSet = CharSet.Ansi,
           CallingConvention = CallingConvention.Cdecl)]
public static extern int url_engine_version(StringBuilder version, [Out] int length);

【问题讨论】:

  • 你确定真的是Delphi代码崩溃,而不是DLL函数崩溃? AV 错误信息会告诉你违规代码属于哪个模块。

标签: c delphi header c++builder


【解决方案1】:

转换的主要问题是类型系统的差异。一个好的delphi header不能从c中派生出来。

例如,c 不区分指向一个元素的指针和指向数组的指针。它不区分布尔值和整数。 char* 可以表示以零结尾的字符串、指向字节的指针、指向单个字符的指针、通过引用传递的字符……

在您的示例中,delphi 代码通过引用传递最后一个参数(即作为指向 UInt32 的指针),而 c 代码没有。但我不明白为什么 C# 代码有效。

【讨论】:

    【解决方案2】:

    Project JEDI 为 Delphi 做了很多 C 头文件转换。他们的website 上有一套优秀的资源、教程等。

    他们还有一个可以自动执行此操作的工具,该工具实际上源自 Bob Swart 的原始代码。

    【讨论】:

    • 谢谢.. 将网站添加到我的收藏中。
    【解决方案3】:

    您的实际问题的答案是:不。抱歉。

    但是,我认为在这种情况下,问题很简单......

    您在此处复制的 C 标头是错误的,或者 C# 声明是错误的,或者您很幸运没有让 C# 代码崩溃并像 Delphi 代码那样严重烧毁。

    我认为问题在于 C Header 将 length 参数声明为 SIZE_T,NOT 是指向 SIZE_T 的指针。即它是一个输入参数,而不是一个输出或输入/输出参数。

    您大概使用length 来指定为您在version 中传递的指针分配的缓冲区大小。我进一步假设函数 返回 用于放置在 version 缓冲区中的数据的实际字节数。

    我相信 Delphi 版本崩溃了,因为通过将 length 指定为 var,您通过引用传递 length,即函数接收不是“64”而是指向值“64”的指针,但它使用的是这个指针值,而不是64值。

    C# 代码可能通过将参数声明为 out 来躲避问题(如果 C 标头本身正确,也是错误的)。这可能会转化为一些东西,如果不正确,至少在运行时不会像“破坏性地不正确”。

    我认为只需从长度参数声明中删除“var”即可解决您的问题:

    function url_engine_version(aVersion: PByte; aLength: cardinal): integer; cdecl; external 'corplib.dll';
    

    【讨论】:

    • 完美。你很准。 C 标头是正确的,长度是按值而不是参考。删除 var 解决了这个问题。即将修复 C# 版本。非常感谢....
    • 用户还应确认他的 C 编译器的 size_t 与 Delphi 的 Cardinal 大小相同(即 4 个字节)。
    • @Rob: size_t 是标准 C/C++ 定义的类型,对应于 Cardinal(在 Win32 上),参考:en.wikipedia.org/wiki/Size_t
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2023-03-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-02-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多