[英]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.