gpt4 book ai didi

c++ - 查找符号时,程序不会从正确的库中搜索

转载 作者:太空狗 更新时间:2023-10-29 21:03:53 27 4
gpt4 key购买 nike

我正在向系统添加两个类和库,parent.sochild.so 从它派生。

问题是当程序加载child.so 时,它无法从parent.so 中找到parent 的虚函数定义。

发生了什么,

nm -D child.so 会给出类似的东西(我只是更改了名称)

U _ZN12PARENT15virtualFunctionEv


程序会崩溃运行

_handle = dlopen(filename, RTLD_NOW|RTLD_GLOBAL); //filename is child.so

它会给出一个错误 LD_DEBUG = libs

symbol lookup error: undefined symbol: _ZN12PARENT15virtualFunctionEv (fatal)

我无法解释的是,我尝试使用 GDB LD_DEBUG = symbols,当运行 dlopen 时,日志显示它基本上试图在所有库中查找系统除了 parent.so,其中定义了符号。但是从 libs 日志 parent.so 已经加载并且代码正在运行,并且它与所有其他库位于相同的路径。

 ......
27510: symbol=_ZN12PARENT15virtualFunctionEv; lookup in file=/lib/tls/libm.so.6
27510: symbol=_ZN12PARENT15virtualFunctionEv; lookup in file=/lib/tls/libc.so.6
27510: symbol=_ZN12PARENT15virtualFunctionEv; lookup in file=/lib/ld-linux.so.2
27510: child.so: error: symbol lookup error: undefined symbol: _ZN12PARENT15virtualFunctionEv(fatal)

程序或系统如何管理查找符号定义的库?

我是 Linux 新手,任何人都可以指出一些工作方向吗?

谢谢。

编辑

生成parent.so文件的命令是

c++  -shared  -o parent.so parent.o

类似于 child.so。此处链接是否缺少任何信息?看起来 child 只包括 parent 的头文件。

EDIT2

再次测试后,调用

_handle = dlopen("parent.so", RTLD_NOW|RTLD_GLOBAL);

在崩溃行之前将解决问题,我认为这意味着最初 parent.so 没有加载。但是具体原因我还不是很清楚。

最佳答案

您需要告诉链接器您的库 libchild.so使用 libparent.so 中的功能.在创建子库时执行此操作:

g++ -shared -o libchild.so child_file1.o child_file2.o -Lparent_directory -lparent

请注意,顺序很重要。指定 -lparent在你所有的目标文件之后。您可能还需要通过 -Wl 将其他选项传递给链接器。 g++ 选项。

这可能还不够好。您可能需要添加包含 libparent.so 的库到 LD_LIBRARY_PATH环境变量。

一些陷阱:如果您没有使用 lib 命名这些库前缀你会混淆链接器很多时间。如果您不使用 -fPIC 编译源文件或 -fpic你将没有可重定位的对象。

附录
依赖于其他库的库存在很大的潜在问题。假设您在编译子库源文件时使用 1.5 版的父包。您设法解决了所有库依赖性问题。您已指定您的 libchild.so取决于 libparent.so .你的东西很管用。直到父包的 2.0 版问世。现在你的东西用到哪里就坏了,而且你还没有更改一行代码。

解决这个问题的方法是在构建子库时指定生成的共享库具体依赖于 libparent.so` 的 1.5 版本。

为此,您需要通过 -Wl 将选项从 g++/gcc 传递给链接器。选项。使用 -Wl,<linker_option>,<linker_option>,...如果这些链接器选项需要空格,您需要在 g++ 命令中对它们进行反斜杠转义。几个关键选项是 -rpath-soname .例如,-rpath=/path/to/lib,-soname=libparent.so.1.5 .

请注意:您需要使用 -soname=libparent.so.1.5构建 libparent.so 时的选项。这就是让系统表示您的 libchild.so(1.0 版)依赖于 libparent.so(1.5 版)的原因。而且您不构建 libparent.so。您构建 libparent.so.1.5。 libparent.so 呢?这需要存在,但它应该是指向 libparent.so 的某个编号版本(最好是最新版本)的符号链接(symbolic link)。

现在假设非向后兼容的父版本 2.0 被编译并构建到一个 Shiny 的新 libparent.so.2.0 中,并且 libparent.so 符号链接(symbolic link)到这个 Shiny 的新版本。使用笨重的旧 libchild.so(1.0 版)的应用程序将愉快地使用笨重的旧版本 libparent.so 而不是破坏一切的 Shiny 新版本。

关于c++ - 查找符号时,程序不会从正确的库中搜索,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12945514/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com