如何正确地将C与Delphi静态链接?

时间:2015-10-21 14:24:09

标签: delphi delphi-xe8

如何正确地将C与Delphi静态链接? Delphi发出错误说:

[dcc32错误] Project1.dpr(15):E2065不满意的前向或外部声明:'测试'

C编译器是带有COFF目标文件的Visual C ++。

的Delphi:

program Project1;

{$L C:\Source.obj}

function Test(): Integer; cdecl; external;

begin
  WriteLn(Test);
end.

C:

extern "C" int __cdecl Test()
{
    return 12;
}

int main()
{
    return 0;
}

1 个答案:

答案 0 :(得分:6)

这取决于您使用的C编译器使用的名称修饰。例如,32位bcc32编译器将Test装饰为_Test。所以链接到它的Delphi代码应该是:

function Test(): Integer; cdecl; external name '_Test';

但是编译器之间的装饰确实有所不同,并且您没有说明您正在使用哪种编译器。如果上面的代码没有帮助,那么你应该使用C编译器的工具来转储obj文件并检查其中函数的名称。

另一个问题是您实际上使用的是C ++编译器而不是C编译器。从你使用

可以看出这一点
extern "C" 

无效C.您应该删除它并切换到C编译器。将扩展名从.cpp更改为.c通常足以说服编译器将代码视为C。

如果您开始调用C标准库中的函数,例如malloc和朋友,那么您需要将System.Win.Crtl单元添加到Delphi代码的uses子句中。

另请注意,您不需要(实际上可能不应该)在C代码中实现main函数。如果要将C函数编译为单独的C程序,则将函数放在单独的源文件中,而不是包含main函数的源文件。这样您就可以将源文件编译为对象。您可以将它们链接到C程序或Delphi代码中。但是你不需要在你没有调用的Delphi程序中携带main函数。

在C中,无参数main的正确签名是

int main(void)

同样,您的其他C函数应具有此签名:

int __cdecl Test(void)

当然,__cdecl是默认值,所以我们完全可以省略它:

int Test(void)

让我们把它们放在一起:

<强> C

int Test(void)
{
    return 12;
}

重要的是,您使用C编译器进行编译,而不是作为C ++编译。如果您现在编辑的是MSVC,那么命令行将是:

cl /c source.c

<强>的Delphi

{$APPTYPE CONSOLE}

{$L Source.obj}

function Test: Integer; cdecl; external name '_Test';

begin
  WriteLn(Test);
end.

<强>输出

12