我在尝试使用librbd时遇到了以下链接问题。
下面是我的代码片段。
#include <iostream>
#include <rados/librados.hpp>
#include <rbd/librbd.hpp>
int main(){
// Initialize and open an rbd image
std::string pool = "xxx";
std::string image_name = "xxxx";
int r;
librados::Rados cluster;
librados::IoCtx io_ctx;
librbd::Image image;
librbd::RBD rbd;
r = cluster.init("cinder-ctest");
r = cluster.connect();
r = cluster.ioctx_create(pool.c_str(), io_ctx);
r = rbd.open_read_only(io_ctx, image, image_name.c_str(), NULL);
std::string id;
image.get_id(&id); // <- Where the problem occurs
std::cerr << id << std::endl;
return 0;
}使用以下命令编译时发生错误
$ g++ main.cc -o info -lrbd -lrados
/tmp/ccOpSFrv.o: In function `main':
main.cc:(.text+0x12b): undefined reference to `librbd::Image::get_id(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >*)'
collect2: error: ld returned 1 exit status但是我使用nm来证明get_id的存在:
$ nm -D /usr/lib64/librbd.so | grep get_id
0000000000083d00 T rbd_get_id
000000000008de10 T _ZN6librbd5Image6get_idEPSs
U _ZN8librados7v14_2_05IoCtx6get_idEv它在全球范围内是可见的:
$ readelf -s /usr/lib64/librbd.so | grep get_id
498: 0000000000083d00 70 FUNC GLOBAL DEFAULT 11 rbd_get_id
559: 000000000008de10 54 FUNC GLOBAL DEFAULT 11 _ZN6librbd5Image6get_idEP为什么在编译时出现错误:对librbd::Image::get_id的未定义引用。它显然存在,这让我很好奇。
发布于 2020-03-31 03:31:11
一些背景: C++11通过向几个成员函数添加noexcept说明符,稍微改变了std::string接口,但事实证明,微小的变化意味着libstdc++必须以不兼容ABI的方式重写它们的std::string实现。为了向后兼容,他们保留了旧版本,并将新版本放在内联命名空间中,因此就链接器而言,它被命名为std::__cxx11::basic_string。有关更多信息,请参见此页。
那就是你遇到麻烦的地方。_ZN6librbd5Image6get_idEPSs解记
librbd::Image::get_id(
std::basic_string<
char,
std::char_traits<char>,
std::allocator<char>
>*
)该函数接受旧版本的std::string,但您将向它传递指向新版本的std::string的指针。想必你所拥有的图书馆员的版本要么是用GCC的旧版本建造的,要么是故意针对旧的ABI而建的。
您有几种方法可以解决这一问题:
_GLIBCXX_USE_CXX11_ABI预处理宏定义为0,以告诉libstdc++使用std::string的旧实现。它在技术上并不完全符合C++11和以后的标准修订,但基本上是一样的。
发布于 2020-03-31 03:14:48
似乎您使用了一个与C++11兼容的编译器,它生成_ZN6librbd5Image6get_idEPNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE名称,但是在C++11之前,您的库是使用C++03、C++98或诸如此类的语言编译的。
如果您可以访问库源,请使用C++11重新编译它,如果没有,则以C++03兼容性模式编译程序。
https://stackoverflow.com/questions/60942781
复制相似问题