全球最热门网站,五种关键词优化工具,做校园网站,沈阳设计网站公司哪家好1 问题背景说明
在自己的项目源码中引用libeasysqlite.so时编译成功#xff0c;但运行时遇到问题直接报错#xff0c;找不到符号 symbol#xff1a;_ZN3sql5FieldC1ENSt3__112basic_stringIcNS1_11char_traitsIcEENS1_9allocatorIcEEEENS_10field_typeEi。
2 问题描述和解…1 问题背景说明
在自己的项目源码中引用libeasysqlite.so时编译成功但运行时遇到问题直接报错找不到符号 symbol_ZN3sql5FieldC1ENSt3__112basic_stringIcNS1_11char_traitsIcEENS1_9allocatorIcEEEENS_10field_typeEi。
2 问题描述和解读
使用cfilt查看符号表中未知的这个符号
$cfilt _ZN3sql5FieldC1ENSt3__112basic_stringIcNS1_11char_traitsIcEENS1_9allocatorIcEEEENS_10field_typeEisql::Field::Field(std::__1::basic_stringchar, std::__1::char_traitschar, std::__1::allocatorchar , sql::field_type, int)查询到该符号对应的真实函数为
sql::Field::Field(std::__1::basic_stringchar, std::__1::char_traitschar, std::__1::allocatorchar , sql::field_type, int)
接下来在使用nm命令查询libeasysqlite.so看是否有该符号对应的函数。使用nm命令查看如下所示
.../data/sqlite/build$ nm -gC libeasysqlite.so |grep sql::Field::Field
000000000002fca0 T sql::Field::Field(sql::field_use)
000000000002fd80 T sql::Field::Field(std::__cxx11::basic_stringchar, std::char_traitschar, std::allocatorchar , sql::field_type, int)
0000000000038394 W sql::Field::Field(sql::Field)
00000000000320c4 W sql::Field::Field(sql::Field const)
000000000002fca0 T sql::Field::Field(sql::field_use)
000000000002fd80 T sql::Field::Field(std::__cxx11::basic_stringchar, std::char_traitschar, std::allocatorchar , sql::field_type, int)
0000000000038394 W sql::Field::Field(sql::Field)
00000000000320c4 W sql::Field::Field(sql::Field const)
这里发现并没有我们需要的sql::Field::Field(std::__1::basic_stringchar, std::__1::char_traitschar, std::__1::allocatorchar , sql::field_type, int)方法而是有一个类似的sql::Field::Field(std::__cxx11::basic_stringchar, std::char_traitschar, std::allocatorchar , sql::field_type, int)方法这就说明有可能是编译时使用的链接库不同而导致的问题。
这里是cxx11空间对应的是 C11版本的链接库而我们需要的是__1空间的库也就是C03版本的链接库。那么如何修改呢就是在CMakeList.txt文件中添加一些参数如下所示
set(CMAKE_CXX_COMPILER clang-14)
set(CMAKE_CXX_FLAGS ${CMAKE_CXX_FLAGS} -stdc11 -stdliblibc)
重新编译libeasysqlite.so库。这样在编译生成库的时候就会强制使用C03版本的标准了再次make编译出sql库即可。
接下来开始测试该库。修改后执行nm命令查看如下所示
.../data/sqlite/build$ nm -gC libeasysqlite.so |grep sql::Field::Field
00000000000244b0 T sql::Field::Field(sql::field_use)
0000000000024590 T sql::Field::Field(std::__1::basic_stringchar, std::__1::char_traitschar, std::__1::allocatorchar , sql::field_type, int)
00000000000244b0 T sql::Field::Field(sql::field_use)
0000000000024590 T sql::Field::Field(std::__1::basic_stringchar, std::__1::char_traitschar, std::__1::allocatorchar , sql::field_type, int)
0000000000029e54 W sql::Field::Field(sql::Field)
000000000002734c W sql::Field::Field(sql::Field const)
这样就和我们需要的对上了。
3 问题总结
该类问题的解决步骤如下所示
遇到这类问题时基本上都是使用cfilt来将符号表中的符号转换。确认符号是否在库中如果不在库中那么可能是链接库的版本或者编译方式不对。修正编译方式/库的版本确认符号表中的符号可以对上。接下来进行实测即可。