首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Boost不静态地链接到boost::python共享对象

Boost不静态地链接到boost::python共享对象
EN

Stack Overflow用户
提问于 2012-09-26 23:14:04
回答 2查看 2K关注 0票数 3

我已经使用boost::python为我的应用程序创建了一个包装器。

到目前为止,这已经通过:(静态库/源代码的数量) -> python_mapping.so实现了。

通过这种方式,我的共享对象由许多静态库组成,包括boost本身(特别是boost_thread)。我假设这将包含我的所有应用程序信息,因为我已经静态地将所有内容链接到其中。

这个编译得很好。

代码语言:javascript
复制
ldd python_mapping.so
        librt.so.1 => /lib64/librt.so.1 (0x00002b7cbad37000)
        libstdc++.so.6 => /usr/lib64/libstdc++.so.6 (0x00002b7cbaf40000)
        libm.so.6 => /lib64/libm.so.6 (0x00002b7cbb240000)
        libgcc_s.so.1 => /lib64/libgcc_s.so.1 (0x00002b7cbb4c4000)
        libpthread.so.0 => /lib64/libpthread.so.0 (0x00002b7cbb6d2000)
        libc.so.6 => /lib64/libc.so.6 (0x00002b7cbb8ed000)
        /lib64/ld-linux-x86-64.so.2 (0x000000327ee00000)

然而,当我运行我的示例python应用程序时,我得到了这个运行时链接错误:未定义的符号:_ZTIN5boost6detail16thread_data_baseE

似乎那些与静态库很好地连接的boost库实际上并不存在吗?

我在这方面取得了一些进展。显然,我的共享对象没有包含编译器认为没有被使用的许多符号(因为它从未见过我的c++对象被创建,因为它们是通过实例化Python对象创建的)。

有点像:

代码语言:javascript
复制
//This is a class only created in python
#include "CPlusPlusClass.h"

PythonClass
{
       public:
           PythonClass() { }
       private:
           CPlusPlusClass _cplusplus;
};

//PythonMappings for PythonClass

#python file
import python_mapping

pythonClass = python_mapping.PythonClass() #This fails saying it can't find the symbol for CPlusPlusClass

编译器将优化CPlusCPlus类,因为它从未看到它被实际使用,这是完全令人讨厌的。它似乎确实保留了PythonClass本身(可能是因为PythonClass映射宏。

你可以用几种方法解决这个问题:

  1. 将所有库链接到:-Xlinker --whole-archive
  2. 在共享对象中创建库的虚拟用途

我想知道是否有人能想到另一种解决方案,因为浏览所有可能的库并将它们添加到-完整的存档中是非常烦人的。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2012-09-28 22:33:22

好的,由于没有人响应,我找到了最简单的(也是我所知道的唯一的解决方案)是将您拥有的每个静态库都包括在内:

代码语言:javascript
复制
-Xlinker --whole-archive

当然,您可以动态链接库,这将要求您在执行python应用程序时设置LD_LIBRARY_PATH (尽管对于许多库来说,这不是一个选项)。

因此,在这个意义上,显式动态链接可能被认为是一个更优雅的解决方案。

除此之外,如果您的库使用其他库:

python_mapping.so ->静态链接实用程序1 a ->静态链接实用程序2.a

如果您忘记了在utility1.a中链接,运行python应用程序会让您知道它找不到符号,但是,它不会抱怨utility2.a,并且当它到达库的那个部分时会有奇怪的行为。所以..。要小心,并确保你已经明确地连接在每件事情上。

票数 2
EN

Stack Overflow用户

发布于 2013-06-21 16:07:57

可以使用链接器参数-rpath嵌入库搜索路径,包括可执行文件中的“当前目录”(g++ -Wl,-rpath,.)因此,您可以指定从何处加载共享库。如果您正在将应用程序移动到其他.so文件未知的机器,这将有所帮助。您还必须在您显式指定的.so文件上移动。这是静态链接和完全动态链接之间的折衷,因为您实际上不会与盒子上的其他应用程序“共享”.so文件(您自己带了副本),这是使用共享库节省内存的好处之一。

这篇文章主要是为了宣传很少使用的,但非常有用的-rpath参数。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/12611845

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档