- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我正在使用 C++ dlopen() 在我的主程序(在目录 B 中)中链接名为 lib*.so (在目录 A 中)的共享库。
我尝试了一些简单的函数加载。每件事都运作得很好。然而,当我尝试加载返回类对象指针的类和工厂函数时,这让我很头疼。 (我使用下面教程中的术语)
我使用的方法基于本教程第 3.3 章中的示例 https://www.tldp.org/HOWTO/C++-dlopen/thesolution.html#externC .
这里有一点多态性...... lib*.so 包含一个从主程序目录(目录 B)继承父抽象类的子类。当 dlopen() 尝试在主程序中加载 lib*.so 时,由于“ undefined symbol ”而失败。
我使用 nm 命令检查 lib*.so 和主程序二进制文件中的符号表。这些二进制文件中的符号是:
lib*.so : U _ZTI7ParentBox
主程序二进制文件:V _ZTI7ParentBox
ParentBox是lib*.so中ChildBox继承的父类的名称。请注意,父类头文件位于目录 B 中的另一个项目中。
尽管存在名称修改,但符号名称完全相同。我只是想知道为什么动态链接器无法链接它们?并给我 dlopen() 的 undefined symbol 错误?
我是否缺少对一些关键概念的理解?
附注更奇怪的是,它能够解析lib*.so中的子类(U型符号)(T型符号)和父类之间的成员函数符号。为什么可以做到这一点却无法解析父类名的 undefined symbol ?
(我已经搜索了很长时间并尝试了 -rdynamic、-ldl 的东西,尽管我不完全理解它们是什么,但没有任何效果)
2019 年 4 月 4 日更新:这是我用来制作主程序二进制文件的 g++ 命令行。
g++ -fvisibility=hidden -pthread -static-libgcc -static-libstdc++ \
-m64 -fpic -ggdb3 -fno-var-tracking-assignments -std=c++14 \
-rdynamic \
-o ./build/main-prog \
/some_absolute_path/ParentBox.o \
/some_other_pathen/Triangle.o \
/some_other_pathen/Circle.o \
/some_other_pathen/<lots_of_depending_obj> \
/some_absolute_path/librandom.a \
-lz -ldl -lrt -lbz2
我在 https://gcc.gnu.org/onlinedocs/gcc/Option-Index.html 中搜索了该命令行的每个参数(对于所有处理具有复杂 g++ 行的大型项目的程序员同事来说,这似乎是一个很好的引用站点:))
感谢@Employed Russian 。根据他的指示,问题缩小到导出主程序二进制文件中的符号。
但是,主程序二进制文件有很多依赖项,正如您从上面的命令、Circle、Triangle 和许多其他目标文件中看到的那样。我们还需要在 Circle、Triangle 等依赖对象文件的编译中添加“-rdynamic”。否则它不起作用。
就我而言,我向项目中的所有文件添加了“-rdynamic”以导出所有符号。不确定“-fvisibility=hidden”有什么好处。无论如何,我在我的 Makefile 中删除了所有这些...我知道这不是最好的方法,但稍后当一切功能正确时我会担心速度。 :)
更多更新:正确的解决方案在@Employed Russian 的答案更新中。我之前的解决方案恰好有效,因为我还删除了“-fvisibility=hidden”。没有必要(而且可能是错误的)将 -rdynamic 添加到最终链接中使用的所有对象中。请参阅@Employed Russian 的解释,它解决了核心问题。
最终更新:对于对 C/C++ 程序如何执行以及如何链接库感兴趣的程序员同行,这里有一个很好的引用网络类(class)(二进制的生命),作者是 Xeno Kovah:http://opensecuritytraining.info/LifeOfBinaries.html
您还可以在 YouTube 上找到播放列表。只需搜索“二进制的生命”
最佳答案
Although there is name mangling the symbol names are exactly the same. I'm just wondering why the dynamic linker cannot link them?
最可能的解释:该符号未从主二进制文件中导出。
使用nm -D
重复您的命令:
nm -AD lib*.so main-prog | grep ' _ZTI7ParentBox$'
很可能,您会看到 lib*.so: U _ZTI7ParentBox
而 main-prog
中没有任何内容。
发生这种情况是因为链接器通常不会从 main-prog
导出任何符号,该符号未被参与链接的某些共享库引用(以及您的 lib*.so
code> 未与 main-prog
链接,否则您不需要 dlopen
它)。
要更改该行为,您可以在链接 main-prog
时添加 -Wl,--export-dynamic
链接器标志。这指示链接器导出链接到 main-prog
的所有内容。
tried -rdynamic
这相当于-Wl,--export-dynamic
,并且应该有效(假设您将其添加到main-prog
链接行,而不是某个地方其他)。
更新:
Everything works now! Since main-prog also depends on some other objects, it appears that simply add -rdynamic to the final main-prog linking does not resolve the problem. We need to add "-rdynamic" to the compilation of those depending objects.
这是错误的解决方案。您的问题是 -fvisibility=hidden
告诉编译器将进入 main-prog
的所有符号标记为未导出,并且 -rdynamic
不导出任何隐藏符号。
正确的解决方案是从定义您想要导出的符号的任何对象中删除 -fvisibility=hidden
,并添加 -rdynamic
到最后的链接。
关于c++ - 加载类 - 动态链接库返回 undefined symbol 错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55526965/
我已经使用 vue-cli 两个星期了,直到今天一切正常。我在本地建立这个项目。 https://drive.google.com/open?id=0BwGw1zyyKjW7S3RYWXRaX24tQ
您好,我正在尝试使用 python 库 pytesseract 从图像中提取文本。请找到代码: from PIL import Image from pytesseract import image_
我的错误 /usr/bin/ld: errno: TLS definition in /lib/libc.so.6 section .tbss mismatches non-TLS reference
我已经训练了一个模型,我正在尝试使用 predict函数但它返回以下错误。 Error in contrasts<-(*tmp*, value = contr.funs[1 + isOF[nn]])
根据Microsoft DataConnectors的信息我想通过 this ODBC driver 创建一个从 PowerBi 到 PostgreSQL 的连接器使用直接查询。我重用了 Micros
我已经为 SoundManagement 创建了一个包,其中有一个扩展 MediaPlayer 的类。我希望全局控制这个变量。这是我的代码: package soundmanagement; impo
我在Heroku上部署了一个应用程序。我正在使用免费服务。 我经常收到以下错误消息。 PG::Error: ERROR: out of memory 如果刷新浏览器,就可以了。但是随后,它又随机发生
我正在运行 LAMP 服务器,这个 .htaccess 给我一个 500 错误。其作用是过滤关键字并重定向到相应的域名。 Options +FollowSymLinks RewriteEngine
我有两个驱动器 A 和 B。使用 python 脚本,我在“A”驱动器中创建一些文件,并运行 powerscript,该脚本以 1 秒的间隔将驱动器 A 中的所有文件复制到驱动器 B。 我在 powe
下面的函数一直返回这个错误信息。我认为可能是 double_precision 字段类型导致了这种情况,我尝试使用 CAST,但要么不是这样,要么我没有做对...帮助? 这是错误: ERROR: i
这个问题已经有答案了: Syntax error due to using a reserved word as a table or column name in MySQL (1 个回答) 已关闭
我的数据库有这个小问题。 我创建了一个表“articoli”,其中包含商品的品牌、型号和价格。 每篇文章都由一个 id (ID_ARTICOLO)` 定义,它是一个自动递增字段。 好吧,现在当我尝试插
我是新来的。我目前正在 DeVry 在线学习中级 C++ 编程。我们正在使用 C++ Primer Plus 这本书,到目前为止我一直做得很好。我的老师最近向我们扔了一个曲线球。我目前的任务是这样的:
这个问题在这里已经有了答案: What is an undefined reference/unresolved external symbol error and how do I fix it?
我的网站中有一段代码有问题;此错误仅发生在 Internet Explorer 7 中。 我没有在这里发布我所有的 HTML/CSS 标记,而是发布了网站的一个版本 here . 如您所见,我在列中有
如果尝试在 USB 设备上构建 node.js 应用程序时在我的树莓派上使用 npm 时遇到一些问题。 package.json 看起来像这样: { "name" : "node-todo",
在 Python 中,您有 None单例,在某些情况下表现得很奇怪: >>> a = None >>> type(a) >>> isinstance(a,None) Traceback (most
这是我的 build.gradle (Module:app) 文件: apply plugin: 'com.android.application' android { compileSdkV
我是 android 的新手,我的项目刚才编译和运行正常,但在我尝试实现抽屉导航后,它给了我这个错误 FAILURE: Build failed with an exception. What wen
谁能解释一下?我想我正在做一些非常愚蠢的事情,并且急切地等待着启蒙。 我得到这个输出: phpversion() == 7.2.25-1+0~20191128.32+debian8~1.gbp108
我是一名优秀的程序员,十分优秀!