- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我有一个 Delphi 单元,它使用 {$L xxx}
指令静态链接 C .obj 文件。 C 文件是用 C++Builder 的命令行编译器编译的。为了满足 C 文件的运行时库依赖项(_assert、memmove 等),我包含 Allen Bauer 提到的 crtl
单元 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 必须已经包含必要的函数。
编辑
对于任何想在家玩的人,可以在 Abbrvia 的 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} block ,然后尝试编译 C++构建器“Abbrevia.cbproj”项目。
最佳答案
我对此的看法是,您只需要项目的 Delphi 版本中的 Delphi 单元。
在 C++ 构建器版本中,您只需编译并链接foolib.c,就好像它是一个 C 文件一样(确实如此!)在该程序的 Delphi 版本中,您可以使用 bcc32 创建 .obj,按照所述使用 ctrl 等。
为什么要将其包装在 Delphi 包装器中的 C 库中以便在 C++ 中使用?
编辑 1
您已在评论中添加了说明。
另一个需要考虑的选择是避免 crtl 并实现 FooWrapper 中缺少的函数。我这样做而不是使用 crtl 因为这给了我更多的控制权并且我理解正在调用的内容。例如,我不想调用printf()
泄漏到我的 GUI 应用程序或 DLL 中。
如果您只缺少少数功能,这可能是一个有吸引力的选择。通常,获取它们的最巧妙方法是将它们从 msvcrt.dll 链接到其中,msvcrt.dll 是当今的标准系统组件。当然,仅仅为了获取 memset()
链接到 msvcrt.dll 似乎有点重量级。 , memcpy()
等等
不使用crtl编译Delphi单元时,缺少多少个函数?
编辑2
我将其添加到答案中以显示一些代码。从我自己的代码库中,我提供以下内容:
const
__turboFloat: Longint=0;
(* We don't actually know the type but it is 4 bytes long and initialised to zero. This can be determined
using tdump initcvt.obj. It doesn't actually matter how we define this since it is ultimately not
referred to and is stripped from the executable by the linker. *)
对于ftol
我链接到 ftol.obj,我认为它是从我使用的 BCC55 编译器中的 lib 文件之一中提取的。
我认为strncmp
用普通 Pascal 实现应该是非常常规的。
sprintf
总体而言更困难,但您可能会发现它仅用于一些琐碎的事情,例如整数到字符串。在这种情况下,您可以伪造 C 代码来调用专用于此目的的例程并简单地实现它。
说实话,我认为“msvcrt.dll”看起来很有吸引力!
编辑3
我很快就说话了吗?您可以拉一个完美可用的sprintf
无论如何,几乎所有进程都已经加载了 user32.dll。确保您选择了 wsprintfA
如果您需要的是 ANSI 版本。
编辑4
我注意到_beginthreadex
。你说这是在不同的 Delphi 单元中定义的。为了让编译器看到它,您需要在 AbCtrl.pas 中重新声明它,并从那里调用 AbLzma.pas 中的真实版本。
当您在 Delphi .pas 文件中包含 .obj 时,编译器必须能够从链接到 .obj 的 Delphi 单元中解析 .obj 文件中的所有引用。整个游戏是由编译器而不是链接器处理的。
有时,您会因包含 .obj 文件的顺序而陷入困境,解决方案是使用前向声明,但那是另一个故事了。
关于c - 如何在C++Builder项目的Delphi单元中使用Crtl? (或链接到 C++Builder C 运行时库),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5303568/
我想添加一个在简单计算器上使用 Ctrl 键 + JButton 单击鼠标的快捷方式选项。我知道如何使用 KeyStroke 输入 Ctrl + C 但我不知道如何使用 JButton > 使用鼠标单
将组合键定义为 Ctrl++ 的正确格式是什么? 我尝试过: zoomIn.setAccelerator(KeyCombination.keyCombination("Ctrl + +")) 但我得到
我想使用 Ctrl + ~ 查看电子表格上的公式。 有没有办法将这些“爆炸”公式复制粘贴到“爆炸” View 中的另一个 Excel 工作表上? 最佳答案 我知道一种方法,但它需要一些外部程序。我假设
所以脚本是这样的: use strict; use warnings; use Term::ReadLine; $SIG{'INT'} = 'INT_handler'; sub INT_handler
在 IDEA 的终端中我无法使用(尝试使用 zsh - /usr/bin/zsh 和 bash - /bin/sh) Home, End - 按下时没有任何反应,也没有 Ctrl+箭头键 - 获取 A
假设我有以下代码: 但我改变主意,我不想叫它plan了。我想叫它schedule .所以,因为 VS Code 太棒了,我又太懒了,我按 希望VS Code根据案例更改名称。但突然: 有什么办法可以告
我正在尝试将 Eclipse 用作 C++ IDE,因为我已经习惯了 Java 世界中的 Eclipse 快捷方式。但是,使用 (crtl+2-l) 将表达式的结果分配给新的局部变量在 C/C++ 透
我是一名优秀的程序员,十分优秀!