共享库符号查找模板实例化

Posted

技术标签:

【中文标题】共享库符号查找模板实例化【英文标题】:Shared library symbol lookup template instantiation 【发布时间】:2021-05-28 22:59:25 【问题描述】:

我正在使用一个共享库实用程序,它从共享库中查找符号(在非 Windows 平台上使用 GetProcAddress)。 这适用于正常功能。 但是,我需要一个函数,它是命名空间中的模板实例化。 我已使用 nm -gDC lib.so 确认该库包含该符号,并且在我的查找尝试中拼写完全相同,但找不到。nm -gDC lib.so

...
0000000000009575 T rosidl_service_type_support_t const* rosidl_typesupport_cpp::get_service_type_support_handle<example_interfaces::srv::AddTwoInts>()
...

我试着查了一下:

GetProcAddress((HINSTANCE)(lib), "rosidl_typesupport_cpp::get_service_type_support_handle<example_interfaces::srv::AddTwoInts>");

但它返回一个nullptr。 对于我找不到的模板实例化是否有一些特殊处理? 我找到了一种不同的方法,可以返回我需要的东西,但我仍然对任何关于为什么它不起作用的资源感兴趣!

【问题讨论】:

删除-C 选项。你想要错位的名字,这就是 GetProcAddress 期望的名字。 啊,谢谢你说得有道理。但是,名称修饰取决于编译器,对吗?所以这不会是编译器可移植的,更不用说平台无关了。 你不能指望独立于平台的二进制文件; lib.so 肯定无法在 Windows、Mac 或 android 手机上运行。是的,名称修饰方案通常是特定于编译器的;如果您想从库中导出一些可移植的名称,请坚持使用纯 C 函数。 【参考方案1】:

我已确认使用 nm -gDC lib.so 库包含符号并且在我的查找尝试中拼写完全相同,但找不到。

正如 Igor Tandetnik 正确评论的那样,库实际上导出的名称是 C++ mangled 名称,不是 rosidl_typesupport_cpp::get_service_type_support_handle&lt;example_interfaces::srv::AddTwoInts&gt; (这是解构的名称)。

要查看实际符号名称,请使用nm -D lib.so(特别是省略-C标志)。

【讨论】:

以上是关于共享库符号查找模板实例化的主要内容,如果未能解决你的问题,请参考以下文章

当从属共享库包含符号时 ,Java JNI“符号查找错误”

如何使共享库符号强大?

当另一个库具有相同的符号时,gdb 不显示来自共享库的符号

Linux C++ libdl.so dlfcn.h使用方法(dlopen()dlsym()dlclose()dlerror())(用于动态链接库操作)(懒加载立即加载)共享库符号动态库

共享对象中的符号

从堆栈跟踪中查找共享库中的源代码行