简体   繁体   English

使用`dlopen`时有关“未定义符号”的共享库错误

[英]shared library error about “undefined symbol” when using `dlopen`

First thing first, here's my minimum reproducible program:首先,这是我的最小可重现程序:

CMakeLists.txt: CMakeLists.txt:

cmake_minimum_required(VERSION 3.17)
project(untitled4)

set(CMAKE_CXX_STANDARD 17)

add_library(lib1 SHARED lib1.cpp)

add_executable(untitled4 main.cpp)
target_link_libraries(untitled4 PRIVATE dl)

main.cpp:主.cpp:

#include "iostream"
#include <dlfcn.h>
int Test() {
  return 123456;
}
int main() {
  auto* handler = dlopen("/home/liu/source/untitled4/cmake-build-debug/liblib1.so", RTLD_LAZY|RTLD_GLOBAL);
  if (!handler) {
    std::cerr << dlerror();
    exit(1);
  }
}

and lib1.cpp:和 lib1.cpp:

#include "iostream"
extern int Test();
class Foo {
 public:
  Foo() {
    std::cout << Test() << std::endl;
  }
};
Foo foo;

now let me explain:现在让我解释一下:

As you can see I defined a function called Test in main.cpp, and I want to the shared library liblib1.so call it when it is loaded.如您所见,我在 main.cpp 中定义了一个名为Test的 function,我希望共享库liblib1.so在加载时调用它。

But when I run the main() function, there's an error log said:但是当我运行main() function 时,有一个错误日志说:

/home/liu/source/untitled4/cmake-build-debug/liblib1.so: undefined symbol: _Z4Testv

I check the symbol by using nm untitled4 |grep Test and the symbol seems exist:我使用nm untitled4 |grep Test检查符号,符号似乎存在:

0000000000000b87 t _GLOBAL__sub_I__Z4Testv
0000000000000aea T _Z4Testv

So what did I do wrong?那么我做错了什么? How to fix this?如何解决这个问题?

An important thing to be notice is that in the real case, the build of lib1 and the build of main.cpp are totally separated, the two build don't know each other.需要注意的重要一点是,在实际情况下, lib1的构建和main.cpp的构建是完全分开的,两个构建彼此不认识。 But I can make them into one build (very difficult) if this can fix the problem(if there's no other way).但是如果这可以解决问题(如果没有其他方法),我可以将它们组合成一个版本(非常困难)。

PS I tried using extern "C" to wrap around the Test() in both files, but not working, seems not the C/C++ function naming problem. PS 我尝试在两个文件中使用 extern "C" 来环绕Test() ,但没有工作,似乎不是 C/C++ function 命名问题。

With the addition of the linker option -rdynamic your code does not fail with " undefined symbol ".添加 linker 选项-rdynamic您的代码不会因“未定义符号”而失败。

You can set that with set_target_properties(untitled4 PROPERTIES ENABLE_EXPORTS 1) or target_link_options(untitled4 BEFORE PRIVATE "-rdynamic") .您可以使用set_target_properties(untitled4 PROPERTIES ENABLE_EXPORTS 1)target_link_options(untitled4 BEFORE PRIVATE "-rdynamic")进行设置。

Example:例子:

cmake_minimum_required(VERSION 3.17)
project(untitled4)

set(CMAKE_CXX_STANDARD 17)

add_library(lib1 SHARED lib1.cpp)

add_executable(untitled4 main.cpp)
set_target_properties(untitled4 PROPERTIES ENABLE_EXPORTS 1)

target_link_libraries(untitled4 PRIVATE dl)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM