如何在C ++ Builder项目中的Delphi单元中使用Crtl? (或链接到C ++ Builder C运行时库)
我有一个Delphi单元,使用
{$L xxx}
指令静态链接C .obj文件。 C文件是使用C ++ Builder的命令行编译器编译的。为了满足C文件的运行时库依赖关系(_assert,memmove等),我将包括这里提到的crtl
单元Allen Bauer。
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)中编译该单元,则everthing工作正常。
如果我在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的文章了。如果可能的话,我想避免手动编写Delphi包装器,因为我在Delphi中不需要它们,并且C ++ Builder必须已经包含必要的功能。
编辑
对于任何想在家中玩游戏的人来说,代码可以在Abbrevia的Subversion存储库中找到,网址是https://tpabbrevia.svn.sourceforge.net/svnroot/tpabbrevia/trunk。我采用了David Heffernan的建议,并在C ++ Builder中编译时添加了一个模仿crtl.dcu的“AbCrtl.pas”单元。这使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编译使用。
要自己查看,只需下载trunk(或只是“source”和“packages”目录),禁用AbDefine.inc底部的{$ IFDEF BCB}块,并尝试编译C ++ Builder“Abbrevia .cbproj“项目。
没有找到相关结果
已邀请:
3 个回复
遣莫捅炭
泄漏到我的GUI应用程序或我的DLL中。 如果您只缺少一些功能,这可能是一个很有吸引力的选择。通常,获取它们的最佳方法是将它们与msvcrt.dll链接起来,msvcrt.dll是目前的标准系统组件。当然,在msvcrt.dll中链接似乎有点重量只是为了获得
,
等。 在没有crtl的情况下编译Delphi单元时有多少缺少的函数? 编辑2 我将此添加到答案中以显示一些代码。从我自己的代码库我提供:
对于
我在ftol.obj中链接,我认为我是从我使用的BCC55编译器中的一个lib文件中提取的。 我认为在普通的Pascal中实现
应该是非常常规的。
在完全通用性方面更难,但您可能会发现它仅用于像整数到字符串这样的小事。在这种情况下,您可以捏造C代码来调用专用于此的例程并轻松实现它。 说实话,我觉得'msvcrt.dll'看起来很有吸引力! 编辑3 我很快就说话了吗?您可以从user32.dll中提取一个完全可用的
,几乎所有进程都已加载。如果它是您需要的ANSI版本,请务必选择
。 编辑4 我注意到了
。你说这是在不同的Delphi单元中定义的。为了让编译器看到它,你需要在AbCtrl.pas中重新声明它,并从那里调用AbLzma.pas中的真实版本。 当您在Delphi .pas文件中包含.obj时,编译器必须能够从链接到.obj的Delphi单元中解析.obj文件中的所有引用。整个游戏由编译器而不是链接器处理。 有时你会遇到包含.obj文件的顺序纠结在一起,解决方案是使用前向声明,但这是另一个故事。
容淑阔九
凄嘛姥
现在你可以使用crtl.dcu而不会出现内部错误!