#pragma directive
#pragma package(smart_init)
#pragma package(smart_init)確保已打包的單元按照其依賴關系確定的順序進行初始化(默認情況下包含在package(包)源文件中。)通常,您將#pragma package用于作為package(包)構建的.cpp文件。簡而言之就是按照單元的依賴關系順序進行初始化,一般用于構建Package(軟件包)中
注意:不要在頭文件中使用#pragma package(smart_init)。 這樣做可能導致編譯器錯誤。
該編譯指令影響該編譯單元的初始化順序。 對于單元,初始化按以下順序進行:
1)根據它們的“uses”依賴性,即,如果unitA依賴于unitB,則必須在unitA之前初始化unitB。
2)鏈接順序。
3)單元(unit)內的優先級順序。
對于常規目標文件(obj文件)(不是作為單元(unit)構建的目標文件),首先根據優先級順序進行初始化,然后根據鏈接順序進行初始化。 更改對象文件的鏈接順序將更改全局對象構造函數的調用順序。
以下示例顯示了單元和常規目標文件之間的初始化有何不同。
假設您有三個源文件A,B和C,它們使用#pragma package(smart_init)“智能初始化”,并且具有優先級設置為10、20和30的函數(由#pragma startup的優先級參數定義)。這些函數是根據其優先級值和父源文件命名的,因此名稱分別為a10,a20,a30,b10,b20等。這是三個程序A,B和C:
// A.cpp #include <stdio.h> #ifdef USE_PACKAGE_INIT #pragma package(smart_init) #endif void A10() { printf("%s() ", __FUNCTION__); } #pragma startup A10 10 void A20() { printf("%s() ", __FUNCTION__); } #pragma startup A20 20 void A30() { printf("%s() ", __FUNCTION__); } #pragma startup A30 30
// B.cpp #include <stdio.h> #ifdef USE_PACKAGE_INIT #pragma package(smart_init) #endif void B10() { printf("%s() ", __FUNCTION__); } #pragma startup B10 10 void B20() { printf("%s() ", __FUNCTION__); } #pragma startup B20 20 void B30() { printf("%s() ", __FUNCTION__); } #pragma startup B30 30
// C.cpp #include <stdio.h> #ifdef USE_PACKAGE_INIT #pragma package(smart_init) #endif void C10() { printf("%s() ", __FUNCTION__); } #pragma startup C10 10 void C20() { printf("%s() ", __FUNCTION__); } #pragma startup C20 20 void C30() { printf("%s() ", __FUNCTION__); } #pragma startup C30 30
如果按編寫的方式并定義了USE_PACKAGE_INIT來構建源文件,則會打印出以下內容:
> A10() A20() A30() B10() B20() B30() C10() C20() C30()
也就是說,優先級被忽略,每個單元一次運行其所有初始化。
如果您在未定義USE_PACKAGE_INIT的情況下構建源文件,則會得到完全不同的結果。 在這種情況下,運行程序時,將輸出以下內容:
> A10() B10() C10() A20() B20() C20() A30() B30() C30()
也就是說,使用 startup優先級順序。
由于這三個都是單元,并且如果A uses B和C,并且鏈接順序是A,B,C,則初始化的順序是:
> B10()B20()B30()C10()C20()C30() A10()A20()A30()
如果以上是目標文件,而不是單元,則順序為:
> A10()B10()C10()A20()B20()C20()A30()B30()C30()
使用#pragma package(smart_init)的.cpp文件還要求從任意聲明#pragma pragma(smart_init)的.cpp文件中到其他目標文件的任何#pragma link引用都必須由一個單元解析。仍然可以通過庫解析對非對象文件的#pragma link引用,依此類推。
#pragma package(smart_init, weak)
#pragma package(smart_init,weak)指令會影響對象文件在包的.bpi和.bpl文件中的存儲方式。 如果#pragma package(smart_init,weak)出現在單元文件中,則編譯器將在可能的情況下從BPL中忽略該單元,并在另一個應用程序或程序包需要時創建該單元的未打包的本地副本。 使用此偽指令編譯的單元被稱為“弱包裝”。
#pragma package(smart_init,weak)用于消除可能依賴于同一外部庫的程序包之間的沖突。
包含#pragma package(smart_init,weak)指令的單元文件不得具有全局變量。
#pragma link
語法:
#pragma link "[path]modulename[.ext]"
#pragma link指令指示鏈接程序將指定文件鏈接到可執行文件中。
使用path參數指定目錄。 缺省情況下,鏈接器在本地目錄和鏈接器的-L選項指定的任何路徑中搜索模塊名稱。
只要您使用默認文件類型,就不要指定modulename的文件擴展名(.ext)。 鏈接器為modulename的文件擴展名(.ext)假定以下默認值:
.objextension for BCC32.oextension for Clang-enhanced C++ compilers
因此,如果省略.ext,則會根據您當前的目標平臺自動使用正確的擴展名。

浙公網安備 33010602011771號