糖尿病康复,内容丰富有趣,生活中的好帮手!
糖尿病康复 > C++中ABI的问题——1.ABI问题的产生

C++中ABI的问题——1.ABI问题的产生

时间:2018-08-11 15:33:02

相关推荐

C++中ABI的问题——1.ABI问题的产生

春招结束,发现面试的后面几面,会闻到c++的abi问题,大致问题就是,gcc编译的库,clang能用吗,或者在升级so文件的时候要注意什么,当时不知道,现在来总结一下。

这个abi问题,网上资料不是很多,有一些零零散散的,最后自己总结了一下以后,在这里做个笔记。

一般的软件为了模块分割,思路都是这样的:

模块写在so/dll文件中,使用exe加载并执行功能,更新只用更新dll、so就可以了。不用重新编译exe

这是一篇ABI兼容的文章/p/895451c7b678

ABI兼容的目的就是为了保证改变了dll,so以后,不用重新编译exe就可以直接使用。

当ABI不兼容,或者ABI出错的时候,会发生什么呢?我们来看一个例子

先给出一个继承图:

vclass -> obj

//interface.h#include<string>class vclass{public:std::string name;virtual std::string get_name()=0;};

//lib.h,继承自interface,重写虚函数#include"interface.h"#include<string>class obj : public vclass{public:std::string get_name();//获得nameobj(){name="子类";}};extern "C" vclass* get_obj(){ //使用C格式的函数命名return new obj;}

//lib的实现#include"lib.h"std::string obj::get_name(){return name;}

很简单的例子吧,就是实现了一个接口,然后返回name的值,随后我们在main中调用dlopen,来打开这个动态链接库:

#include<iostream>#include<memory>#include<dlfcn.h>#include"interface.h"using namespace std;int main(){void *handle=dlopen("./lib.so",RTLD_NOW);//加载so文件using func= vclass*(*)(void);func get_obj;get_obj=(func)dlsym(handle,"get_obj");//从so中获取函数vclass *obj1=(get_obj()); //获取一个对象cout<<obj1->get_name()<<endl; //能够成功得到子类的对象return 0;}

运行的结果很显而易见,直接会输出动态库中的"子类“

#makefilelib:lib.h lib.cpp g++ -g -fPIC -shared -o lib.so lib.cppmain:main.cppg++ -g main.cpp -o main -ldl

ok,现在问题来了,现在有另外一个同事,由于某种需求,在父类加了一个虚函数xxxx(),并且在get_name()虚函数前(这个顺序非常重要,因为虚函数表):

#include<string>class vclass{public:std::string name;virtual std::string xxxx(){return "哈哈哈哈";}virtual std::string get_name()=0;};

那么现在保持子类不动,main也不编译,直接重新编译lib

#makefilelib:lib.h lib.cpp g++ -g -fPIC -shared -o lib.so lib.cpp

现在运行main,你就会发现,我的get_name()呢?去哪了?怎么变成哈哈哈哈了?

这就是ABI的一个特点。

因为加入了新的一个虚函数,使得原来虚函数表的顺序由:

get_name;

变成了:

xxxx

get_name

但是main.cpp 中的obj->get_name(),在汇编中只是访问虚函数表中特定偏移量的函数,在这个例子中,访问的是虚函数表中第一个函数。那么我们通过修改虚函数表的大小,就会导致函数运行出错。所以,一旦涉及到需要动态运行so的,就要考虑到abi了。业界比较常用的,保持C++ ABI兼容的方法是Q指针和D指针,这个我们其他文章再慢慢道来。

如果觉得《C++中ABI的问题——1.ABI问题的产生》对你有帮助,请点赞、收藏,并留下你的观点哦!

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。