Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/windows/15.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 如何始终包含静态库中的符号?_C_Windows_Linux - Fatal编程技术网

C 如何始终包含静态库中的符号?

C 如何始终包含静态库中的符号?,c,windows,linux,C,Windows,Linux,假设我有一个静态库libx.a。如何使这个库中的一些符号(不是全部)始终出现在我与库链接的任何二进制文件中?原因是我需要通过dlopen+dlsym提供这些符号。我知道--整个归档链接器切换,但它强制将库归档中的所有对象文件链接到生成的二进制文件中,这不是我想要的 到目前为止的观察(CentOS 5.4,32位)(upd:这一段是错误的;我无法重现这种行为) 将愉快地剥离所有未引用的符号,而 ld main.o -L. -lx 将连接整个图书馆。不过,我想这取决于所使用的binutils版本,

假设我有一个静态库libx.a。如何使这个库中的一些符号(不是全部)始终出现在我与库链接的任何二进制文件中?原因是我需要通过dlopen+dlsym提供这些符号。我知道--整个归档链接器切换,但它强制将库归档中的所有对象文件链接到生成的二进制文件中,这不是我想要的

到目前为止的观察(CentOS 5.4,32位)(upd:这一段是错误的;我无法重现这种行为)

将愉快地剥离所有未引用的符号,而

ld main.o -L. -lx
将连接整个图书馆。不过,我想这取决于所使用的binutils版本,较新的链接器将能够从静态库中挑选单个对象

另一个问题是如何在Windows下实现相同的效果


提前谢谢。任何提示都将不胜感激。

首先,我将把您一直需要的符号拆分成一个单独的库,只保留
libx中的可选符号。a

获取您需要包含的符号的地址


如果gcc的Optimizer消除了它,用这个地址做点什么就足够了。

第一件事:ld main.o libx.a没有生成有效的可执行文件。一般来说,您不应该使用
ld
直接链接任何内容;请始终使用正确的编译器驱动程序(在本例中为gcc)

另外,
“ld main.o libx.a”
“ld main.o-L-lx”
应该完全等效。我很怀疑你从这两个命令中得到了不同的结果

现在回答您的问题:如果要从
a.out
导出
foo
bar
baz
,请执行以下操作:

gcc -Wl,-u,foo,-u,bar,-u,baz main.o -L. -lx -rdynamic
更新:
您的声明:“我想包含的符号仅由库内部使用”没有多大意义:如果符号是库内部的,为什么要导出它们?如果其他人使用它们(通过dlsym),那么它们不是库的内部——它们是库公共API的一部分


你应该澄清你的问题,并解释你真正想要达到的目标。提供示例代码也不会有什么坏处。

想象一下,您有一个项目,在同一个文件夹中包含以下三个C文件

// ---- jam.h
 int jam_badger(int);

// ---- jam.c
 #include "jam.h"
 int jam_badger(int a)
 {
   return a + 1;
 }

 // ---- main.c
 #include "jam.h"
 int main()
 {
   return jam_badger(2);
 }
你用一个像这样的boost-build-bjam文件来构建它

lib jam : jam.c <link>static ;

lib jam_badger : jam ;

exe demo : jam_badger main.c ;
(我在这里使用bjam是因为该文件更易于阅读,但您可以使用任何您想要的东西)

删除“static”会生成一个工作二进制文件,将static添加到另一个库中,或者只使用一个库(而不是在另一个库中愚蠢地包装)

之所以会发生这种情况,是因为ld足够聪明,只选择实际使用的存档部分,在本例中,这些部分都不是

解决方案是用-Wl,--整个归档和-Wl,--没有整个归档包围静态归档,就像这样

g++ -o "libjam_candle_badger.so" -Wl,--whole-archive libjam_badger.a Wl,--no-whole-archive

不太清楚如何让boost build为您实现这一点,但您已经明白了。

谢谢,但我已经想到了这一技巧;我想知道是否有干净的方式来做它。”Kulbsa:我不认为这是一个黑客。您需要以某种方式引用符号,以使链接器将它们拉入。@qrld是的,但这种方式我必须使符号在当前不可见的某些位置可见(它们只是位于单独的对象文件中…。@kolbusa我没有得到它。如果这些符号不可见,
dlsym()
找不到它们,因此它们必须可见。@qrld我的意思是我需要将这些地址操作放入一个a)公开可见且b)始终被调用的函数中。我确实有这样一个函数,但我的意思是,从代码模块化的角度来看,把这样的代码放在那里没有多大意义。实际上,我现在无法直接复制-l和指定库之间的差异。也许我当时做错了什么。。。2.虽然-u看起来像一个解决方案,但要使用它,我需要知道构建二进制文件时“额外”符号的列表。我想“隐藏”这些依赖项(我想包含的符号仅由库内部使用)。这似乎是实现目标的最简单、最实用的方法,但我相信OP需要一个更优雅的解决方案:)@Motishner:Easy and practical is is优雅;-)天哪,这一定是我最老的帖子之一,所以…:-我认为应该有一个链接器标志,类似于-整个存档或类似的东西。我来问这个问题和答案是因为我现在遇到了相反的问题。我的静态库的符号不会“通过”我的Xcode框架(这是一种动态库),我不明白为什么。你有没有办法通过Apple Xcode构建设置做到这一点?Xcode为自己构建命令行。使用它的“构建设置”表单,您可以修改它的工作方式,从而间接引入链接器标志,另外您还可以添加自己的“其他链接器标志”,但我认为它们不会“环绕”特定的输入文件/静态库。
undefined reference to `jam_badger'
g++ -o "libjam_candle_badger.so" -Wl,--whole-archive libjam_badger.a Wl,--no-whole-archive