【发布时间】:2019-04-25 03:20:57
【问题描述】:
在嵌入式设备(ARM、uClibc)上工作,我有一个静态可执行文件,它与不同的库静态链接,并具有使用 dlopen 的动态加载功能。
set(EXTERNAL_LIBS "-lpthread -lpcap -lcurl -ldl")
target_link_libraries(myApp -static ${EXTERNAL_LIBS})
加载简单插件时,一切工作正常。
void plugin::execute() {
std::cout << "hello world" << std::endl;
}
添加字符串变量时:
void plugin::execute() {
//THIS IS NOT WORKING
std::string test = "hello world from thing";
std::cout << test << std::endl;
}
我明白了:
“无法解析符号 '_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEC1EPKcRKS3_'”
我已尝试按照此处的建议添加 -rdynamic: dlopen a dynamic library from a static library, when the dynamic library uses symbols of the static one 通过添加:
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -rdynamic -Wl,-export-dynamic")
但还是不行。
缺少的符号确实存在于静态二进制文件中(使用 nm 验证)
我在这里错过了什么??
添加了构建过程的简化输出:
编译目标文件
arm-linux-uclibcgnueabi-g++ -fPIC -std=gnu++98 -o CMakeFiles/libstaticlib.dir/test1.cpp.o -c /work/src/test1.cpp
arm-linux-uclibcgnueabi-gcc -fPIC -std=gnu++98 -o CMakeFiles/libstaticlib.dir/test2.cpp.o -c /work/src/test2.cpp
链接 CXX 静态库
arm-linux-uclibcgnueabi-ar qc libstaticlib.a CMakeFiles/libstaticlib.dir/test1.cpp.o CMakeFiles/libstaticlib.dir/test2.cpp.o
arm-linux-uclibcgnueabi-ranlib libstaticlib.a
编译我的应用程序
arm-linux-uclibcgnueabi-g++ -fPIE -std=gnu++98 -o CMakeFiles/myapp.dir/main.cpp.o -c /work/src/main.cpp
链接 CXX 可执行文件
arm-linux-uclibcgnueabi-g++ -rdynamic CMakeFiles/myapp.dir/main.cpp.o -o myapp -L/work/lib -Wl,-rpath,/work/lib -rdynamic -static libstaticlib.a -lpthread -lpcap -lcurl -ldl
编译插件
arm-linux-uclibcgnueabi-g++ -fPIC -std=gnu++98 -o CMakeFiles/plugin.dir/plugin/plugin.cpp.o -c /work/src/plugins/plugin/plugin.cpp
链接 CXX 共享库 ../libplugin.so
arm-linux-uclibcgnueabi-g++ -fPIC -shared -Wl,-soname,libplugin.so -o ../libplugin.so CMakeFiles/plugin.dir/plugin/plugin.cpp.o -L/work/lib
readelf -s myapp 的输出 | grep ...:
0021ce74 68 FUNC WEAK DEFAULT 2 _ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEC1EPKcRKS3_
【问题讨论】:
-
“缺少的符号确实存在于静态二进制文件中(使用 nm 验证)”。请添加
readelf --dyn-syms myapp | grep _ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEC1EPKcRKS3_的实际输出作为证据 -
readelf --dyn-syms myapp 没有输出(可能是因为 myapp 是静态的?) nm 给出以下信息:0021ce74 W ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEC1EPKcRKS3
-
nm正在向您展示全局符号表。nm -D将显示动态符号表,它不会在那里。尽管有-rdynamic,但它没有被导出用于动态链接,但没有你的代码或minimal reproducible example,这是我所能得到的,抱歉。 -
想通了,学到了一些东西。查看更新的答案。
标签: c++ static-libraries dynamic-linking dynamic-loading