问题
I'm maintaining the VirtualTreeView component for Delphi and C++Builder. With Delphi everything is okay but when I compile the packages with the C++Builder the code in the initialization part in the Delphi units is not called. Any ideas?
回答1:
When a Delphi unit's initialization
/finalization
sections are not being called in a C++Builder project, it usually means the Delphi unit is not being linked into the final executable, typically because the C++ code is not directly referencing any code in the unit, so it gets optimized out. C++Builder is a bit more aggressive about removing unused code than Delphi is. In Delphi, simply adding a unit to a uses
clause forces that unit to be linked to. That is not the case in C++. #include
ing a Delphi unit's .hpp
file in C++ code is not enough to guarantee the unit is linked to, if the C++ code does not use anything from the .hpp
file.
Indy ran into this problem in several of its units, most notably IdAllAuthentications
, IdAllFTPListParsers
, and IdAllHeaderCoders
. These units all contain only initialization/finalization code, no interface code, so their generated .hpp
files were basically empty. To force linkage, I had to add {$HPPEMIT}
statements to the interface
section to output #pragma link
statements in the generated .hpp
files. For example:
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} was introduced in XE5 Update 2, to help with linking units that use unit-scope names:
New: You can now use HPPEMIT Delphi compiler directives for linking and generating C++ namespace declarations.
...
{$HPPEMIT LINKUNIT} replaces #pragma link for the iOS device target platform. For more information, see HPPEMIT.
For C++ applications,
{$HPPEMIT LINKUNIT}
replaces#pragma link
on mobile platforms.The Delphi run time has units that must be linked in order to enable some functionality. In C++, auto-linking was previously achieved using the following directive:
{$HPPEMIT '#pragma link "<unitname>"'}
Now you should use the following directive instead:
{$HPPEMIT LINKUNIT}
LINKUNIT
generates a #pragma link
statement that references the calling unit using the correct decorated/namespaced unit name.
来源:https://stackoverflow.com/questions/33738153/the-initialization-part-is-not-called