不调用初始化部分

时间:2015-11-16 14:49:43

标签: delphi linker initialization c++builder virtualtreeview

我正在为Delphi和C ++ Builder维护VirtualTreeView组件。使用Delphi一切都很好但是当我使用C ++ Builder编译软件包时,Delphi单元初始化部分中的代码不会被调用。有什么想法吗?

1 个答案:

答案 0 :(得分:8)

当在C ++ Builder项目中没有调用Delphi单元的initialization / finalization部分时,通常意味着Delphi单元没有被链接到最终的可执行文件中,通常是因为C ++代码不直接引用单元中的任何代码,因此它会得到优化。 C ++ Builder在删除未使用的代码方面比Delphi更具攻击性。在Delphi中,只需向uses子句添加单元就会强制将该单元链接到。在C ++中并非如此。如果C ++代码不使用#include文件中的任何内容,{{1}用C ++代码中的Delphi单元.hpp文件不足以保证单元被链接。

Indy在其中的几个单元中遇到了这个问题,最值得注意的是.hppIdAllAuthenticationsIdAllFTPListParsers。这些单元都只包含初始化/终结代码,没有接口代码,因此它们生成的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语句,该语句使用正确的装饰/命名空间单元名称引用调用单元。