[英]How to force inclusion of an object file in a static library when linking into executable?
我有一個C ++項目,由於其目錄結構被設置為靜態庫A
,它鏈接到共享庫B
,它鏈接到可執行文件C
(這是一個使用CMake的跨平台項目,所以在Windows上我們得到A.lib
, B.dll
和C.exe
,在Linux上我們得到libA.a
, libB.so
和C
)圖書館A
有一個init函數( A_init
,在A/initA.cpp
定義),從庫B
的init函數( B_init
,在B/initB.cpp
定義)調用,從C
的main調用。 因此,在連接時B
, A_init
(和中定義的所有符號initA.cpp
)被鏈接到B
(這是我們所希望的行為)。
問題在於A
庫還定義了一個動態加載的函數( Af
,在A/Afort.f
定義)(即Windows上的LoadLibrary
/ GetProcAddress
和Linux上的dlopen
/ dlsym
)。 由於庫B
中沒有對Af
引用,因此A/Afort.o
中的符號不包括在B
。 在Windows上,我們可以通過使用pragma人工創建引用:
#pragma comment (linker, "/export:_Af")
由於這是一個pragma,它只適用於Windows(使用Visual Studio 2008)。 為了使它在Linux上運行,我們嘗試將以下內容添加到A/initA.cpp
:
extern void Af(void);
static void (*Af_fp)(void) = &Af;
這不會導致符號Af
包含在B
的最后一個鏈接中。 我們如何強制將符號Af
鏈接到B
?
事實證明我最初的嘗試主要在那里。 以下作品:
extern "C" void Af(void);
void (*Af_fp)(void) = &Af;
對於那些想要一個自包含的預處理器宏來封裝它的人:
#if defined(_WIN32)
# if defined(_WIN64)
# define FORCE_UNDEFINED_SYMBOL(x) __pragma(comment (linker, "/export:" #x))
# else
# define FORCE_UNDEFINED_SYMBOL(x) __pragma(comment (linker, "/export:_" #x))
# endif
#else
# define FORCE_UNDEFINED_SYMBOL(x) extern "C" void x(void); void (*__ ## x ## _fp)(void)=&x;
#endif
因此使用的是:
FORCE_UNDEFINED_SYMBOL(Af)
有一種更好的方法來編寫FORCE_UNDEFINED_SYMBOL宏。 只需將該函數指針強制轉換為void *即可。 然后它適用於任何功能 - 或者數據。 此外,當宏的gcc部分也適用於MSVC時,為什么還要使用MSVC編譯指示。 所以我的簡化版本是:
#define FORCE_UNDEFINED_SYMBOL(x) void* __ ## x ## _fp =(void*)&x;
因此使用的是:
FORCE_UNDEFINED_SYMBOL(Af)
但它必須在包含其符號被剝離的庫的程序中使用。
您可以在構建B時使用--undefined
選項:
g++ -Wl,--undefined,Af -o libB.so ...
嘗試將這些行放入B/initB.cpp
以便它們(希望)在鏈接時強制進入libB.so
庫。
但是你為什么要以這種方式去做呢? 你不能設置它,以便可執行文件引用該函數(或它的調用者),導致鏈接器自動執行正確的操作嗎?
如果你可以使用gcc的C ++ 0x特性( -std = c ++ 0x ),那么函數默認模板參數就可以了。 從當前的c ++標准來看,函數模板不允許使用默認參數。 在c ++ 0x中啟用這些功能后,您可以執行以下操作: -
在靜態庫的一些頭文件中......
template< class T = int >
void Af()
{
}
然后在其對應的cpp文件中使用顯式模板實例化...
template void Af();
這將生成函數Af
的符號,盡管它尚未被調用/引用。 這不會影響調用者,因為由於默認模板參數,您無需指定類型。 只需在函數聲明之前添加template <class T = int >
,並在其實現文件中顯式實例化它。
HTH,
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.