目录
〇、前言
本文原意是写dlopen调用C++的函数以及类的方法的,但是因关于函数符号的问题篇幅过长,故单独拎出来。了解的小伙伴们也可以自行跳过。
一、name mongling
在使用dlopen调用C++的函数和类之前,需要简单的了解一下name mongling。我们在代码里写的每个函数都会变成唯一的符号在程序中。C++有一个函数重载的特性是怎么实现的呢?函数重载简单的说就是允许函数名存在而参数不同的函数存在,比如:
int add(int a, int b); #函数一
double add(double a, double b); #函数二
这个两个函数在c++的程序中使用的是不同的符号,只要符号由函数名和参数类型组成,就可以确保对应的不同符号了。比如函数一可以表示为:add_int_int,函数二表示为:add_double_double。这也是为什么C++函数重载的时候,如果只有返回值不同是不可以的。
二、实验
我们可以看一下真实的情况是什么样的,将下面程序分别命名为add.c和add.cpp进行编译。
//add.c 或 add.cpp
int add(int a, int b)
{
return a+b;
}
int main(int argc, char** argv)
{
return 0;
}
- c语言的应用程序
#编译
gcc add.c -o add_c
#查看符号
nm -e add_c
add.c中add函数的符号为:add。
- c++的应用程序
#编译
gcc add.cpp -o add_cpp
#查看符号
nm -e add_cpp
add.cpp中add函数的符号为:addii,其中ii就是代表两个int型参数。
- extern c的使用
在上述程序中的add函数加上extern "C",将程序命名为add_extern_c.cpp
extern "C" int add(int a, int b)
{
return a+b;
}
int main(int argc, char** argv)
{
return 0;
}
#编译
gcc add_extern_c.cpp -o add_extern
#查看符号
nm -e add_extern
可以看到add的函数符号变成了C语言情况了。
三、总结
C和C++对函数的编译方式不同,所以会导致函数符号不同。在C++程序中可以使用extern "C"使对应的函数使用C的方式进行编译。
参考:《编译原理》