如何正确地将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;
}
答案 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