【发布时间】:2011-07-15 06:50:05
【问题描述】:
我有一个 Delphi 单元,它使用 {$L xxx} 指令静态链接 C .obj 文件。 C 文件是使用 C++Builder 的命令行编译器编译的。为了满足 C 文件的运行时库依赖项(_assert、memmove 等),我包括了 crtl 单元 Allen Bauer 提到的 here。
unit FooWrapper;
interface
implementation
uses
Crtl; // Part of the Delphi RTL
{$L FooLib.obj} // Compiled with "bcc32 -q -c foolib.c"
procedure Foo; cdecl; external;
end.
如果我在 Delphi 项目 (.dproj) 中编译该单元,则一切正常。
如果我在 C++Builder 项目 (.cbproj) 中编译该单元,则会失败并出现错误:
[ILINK32 Error] Fatal: Unable to open file 'CRTL.OBJ'
事实上,RAD Studio 安装文件夹中没有crtl.obj 文件。有.dcu,但没有.pas。尝试将crtdbg 添加到uses 子句(定义_assert 的C 标头)会导致找不到crtdbg.dcu 的错误。
如果我删除 uses 子句,它会失败并出现 __assert 和 _memmove 未找到的错误。
那么,在 C++Builder 项目的 Delphi 单元中,如何从 C 运行时库中导出函数以便它们可用于链接?
我已经知道 Rudy Velthuis 的 article。如果可能的话,我想避免手动编写 Delphi 包装器,因为我在 Delphi 中不需要它们,而且 C++Builder 必须已经包含必要的功能。
编辑
对于任何想在家一起玩的人,代码可在 Abbrevia 的 Subversion 存储库中获取,地址为 https://tpabbrevia.svn.sourceforge.net/svnroot/tpabbrevia/trunk。我采纳了 David Heffernan 的建议并添加了一个“AbCrtl.pas”单元,在 C++Builder 中编译时该单元模仿 crtl.dcu。这使 PPMd 支持工作,但 Lzma 和 WavPack 库都因链接错误而失败:
[ILINK32 Error] Error: Unresolved external '_beginthreadex' referenced from ABLZMA.OBJ
[ILINK32 Error] Error: Unresolved external 'sprintf' referenced from ABWAVPACK.OBJ
[ILINK32 Error] Error: Unresolved external 'strncmp' referenced from ABWAVPACK.OBJ
[ILINK32 Error] Error: Unresolved external '_ftol' referenced from ABWAVPACK.OBJ
AFAICT,它们都被正确声明了,而_beginthreadex实际上是在AbLzma.pas中声明的,所以它也被纯Delphi编译使用。
要自己查看,只需下载主干(或仅下载“源”和“包”目录),禁用 AbDefine.inc 底部的 {$IFDEF BCB} 块,然后尝试编译 C++生成器“Abbrevia.cbproj”项目。
【问题讨论】:
标签: c delphi c++builder .obj