我正在为Delphi和C ++ Builder维护VirtualTreeView组件。使用Delphi一切都很好但是当我使用C ++ Builder编译软件包时,Delphi单元初始化部分中的代码不会被调用。有什么想法吗?
答案 0 :(得分:8)
当在C ++ Builder项目中没有调用Delphi单元的initialization
/ finalization
部分时,通常意味着Delphi单元没有被链接到最终的可执行文件中,通常是因为C ++代码不直接引用单元中的任何代码,因此它会得到优化。 C ++ Builder在删除未使用的代码方面比Delphi更具攻击性。在Delphi中,只需向uses
子句添加单元就会强制将该单元链接到。在C ++中并非如此。如果C ++代码不使用#include
文件中的任何内容,{{1}用C ++代码中的Delphi单元.hpp
文件不足以保证单元被链接。
Indy在其中的几个单元中遇到了这个问题,最值得注意的是.hpp
,IdAllAuthentications
和IdAllFTPListParsers
。这些单元都只包含初始化/终结代码,没有接口代码,因此它们生成的IdAllHeaderCoders
文件基本上是空的。为了强制链接,我必须向.hpp
部分添加{$HPPEMIT}
语句,以在生成的interface
文件中输出#pragma link
语句。例如:
.hpp
XE5 Update 2中引入了 {$HPPEMIT LINKUNIT}
,以帮助链接使用单位范围名称的单位:
新增功能:您现在可以使用HPPEMIT Delphi编译器指令链接和生成C ++命名空间声明。
...
{$ HPPEMIT LINKUNIT} 替换iOS设备目标平台的#pragma链接。 有关更多信息,请参阅HPPEMIT。
对于C ++应用程序,
unit IdAllAuthentications; interface { Note that this unit is simply for listing ALL Authentications in Indy. The user could then add this unit to a uses clause in their program and have all Authentications linked into their program. ABSOLUTELY NO CODE is permitted in this unit. } {$I IdCompilerDefines.inc} // RLebeau 2/14/09: this forces C++Builder to link to this unit so // the units can register themselves correctly at program startup... {$IFDEF HAS_DIRECTIVE_HPPEMIT_LINKUNIT} {$HPPEMIT LINKUNIT} {$ELSE} {$HPPEMIT '#pragma link "IdAllAuthentications"'} {$ENDIF} implementation // uses units that self-register in their initialization sections ... end.
会替换移动平台上的{$HPPEMIT LINKUNIT}
。Delphi运行时具有必须链接的单元才能启用某些功能。在C ++中,以前使用以下指令实现了自动链接:
#pragma link
现在您应该使用以下指令:
{$HPPEMIT '#pragma link "<unitname>"'}
{$HPPEMIT LINKUNIT}
生成一个LINKUNIT
语句,该语句使用正确的装饰/命名空间单元名称引用调用单元。