Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/150.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/linux/26.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
链接到可执行文件时,如何强制在静态库中包含对象文件? 我有一个C++项目,因为它的目录结构被设置为静态库 A/COD>,它被链接到共享库 B/COD>,它被链接到可执行代码代码>代码>。(这是一个使用CMake的跨平台项目,因此在Windows上我们得到a.lib,B.dll和C.exe,在Linux上我们得到libA.a,libB.so,和C)库a有一个init函数(a_init code>,在a/initA.cpp中定义),这是从库B的init函数(B_init,在B/initB.cpp中定义)调用的,它是从C的main调用的。因此,当链接B时,A_init(以及initA.cpp中定义的所有符号)链接到B(这是我们想要的行为)_C++_Linux_Linker_Static Libraries - Fatal编程技术网

链接到可执行文件时,如何强制在静态库中包含对象文件? 我有一个C++项目,因为它的目录结构被设置为静态库 A/COD>,它被链接到共享库 B/COD>,它被链接到可执行代码代码>代码>。(这是一个使用CMake的跨平台项目,因此在Windows上我们得到a.lib,B.dll和C.exe,在Linux上我们得到libA.a,libB.so,和C)库a有一个init函数(a_init code>,在a/initA.cpp中定义),这是从库B的init函数(B_init,在B/initB.cpp中定义)调用的,它是从C的main调用的。因此,当链接B时,A_init(以及initA.cpp中定义的所有符号)链接到B(这是我们想要的行为)

链接到可执行文件时,如何强制在静态库中包含对象文件? 我有一个C++项目,因为它的目录结构被设置为静态库 A/COD>,它被链接到共享库 B/COD>,它被链接到可执行代码代码>代码>。(这是一个使用CMake的跨平台项目,因此在Windows上我们得到a.lib,B.dll和C.exe,在Linux上我们得到libA.a,libB.so,和C)库a有一个init函数(a_init code>,在a/initA.cpp中定义),这是从库B的init函数(B_init,在B/initB.cpp中定义)调用的,它是从C的main调用的。因此,当链接B时,A_init(以及initA.cpp中定义的所有符号)链接到B(这是我们想要的行为),c++,linux,linker,static-libraries,C++,Linux,Linker,Static Libraries,问题在于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上工作(使用VisualSt

问题在于
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上工作(使用VisualStudio2008)。为了让它在Linux上工作,我们尝试将以下内容添加到
A/initA.cpp

extern void Af(void);
static void (*Af_fp)(void) = &Af;
这不会导致符号
Af
包含在
B
的最终链接中。如何强制将符号
Af
链接到
B

您可以在构建B时使用
--undefined
选项:

g++ -Wl,--undefined,Af -o libB.so ...

尝试将这些行放入
B/initB.cpp
,以便(希望)在链接时强制它们进入
libB.so


但你为什么要这样做呢?您不能设置它,使可执行文件引用该函数(或它的调用方),从而使链接器自动执行正确的操作吗?

如果您可以使用gcc(-std=C++0x)的C++0x功能,那么函数默认模板参数可能会起作用。在当前C++标准中,函数模板不允许使用默认参数。在c++0x中启用这些功能后,您可以执行以下操作:-

在静态库的某些头文件中

template< class T = int >
void Af()
{
}
这将为函数
Af
生成符号,尽管它尚未被调用/引用。 这不会影响调用者,因为由于默认的模板参数,您不需要指定类型。只需在函数声明之前添加
模板
,并在其实现文件中显式实例化它


嗯,

原来我最初的尝试主要是在那里。以下工作:

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(Af)
#pragma注释(链接器,“/include:uu mySymbol”)


-u symbol

有一种更好的方法来编写FORCE\u UNDEFINED\u symbol宏。只需将该函数指针转换为void*。然后它与任何函数或数据一起工作。此外,当宏的gcc部分也适用于MSVC时,为什么还要使用MSVC pragmas呢。因此,我的简化版本是:

#define FORCE_UNDEFINED_SYMBOL(x) void* __ ## x ## _fp =(void*)&x;
这是如此使用的:

FORCE_UNDEFINED_SYMBOL(Af)
FORCE_UNDEFINED_SYMBOL(Af)

但它必须用于包含正在剥离符号的库的程序。

C实际上是一种脚本语言前端,B是语言引擎,a是引擎要使用的一组本机代码方法。我们正在实现一种预先存在的语言,它有一个定义良好的外部函数接口。A和B由不同的团队制作;我们更愿意将A-team编写的所有内容都保存在A目录中。不幸的是,这不起作用,因为Af实际上是一个Fortran过程。那么,制作一个调用Af_(…)的“C”包装器(u可以从C’调用FORTRAN函数,即用下划线附加函数名;谷歌的TITY GRITY细节用于参数,我不ABT C++调用FORTRAN)把这个“C”包装从C++中调用。BTW,这就是我为之工作的一个主要金融公司,管理它的古董/蹩脚代码:-这是一个非常不明显的代码,2年后可能会被新手维护者删除。至少宏足够清楚。@ XRYL69,这就是为什么你希望包含评论的原因。在这样的定义之前/之后(希望新手也能阅读评论)。使用C++11,您可能可以使用
auto
和no cast!