C语言调用C++中的函数,extern "C"的含义

C++编译器在将cpp文件编译成库时,导出的函数名会改变,成员函数会通过加一些元素变成全局函数,如果这时候我们需要用C语言调用C++的函数,
就有了一个问题,那就是不知道C++库中导出的函数名,这是由编译器决定的,这个时候就需要用到extern关键字。例子:

test.cpp:
int add(int a, int b)
{
    return a+b;    
}

编译:
g++ -o test.o -c test.cpp
nm -s test.o
查看test.o的符号表,可以发现,并没有add函数,而是有一个_Z3addii的函数名,这就是C++编译器编译之后的函数名,如果我们需要调用此函数,那么
就需要使用这个函数名。

main.c:
#include<stdio.h>
int main()
{
    int i = _Z3addii(1,2);
    printf("i=%d\n",i);
    return 0;
}

编译链接:
gcc -o main.o -c main.c
gcc -o main main.o test.o
./main
可以看到输出为:
i=3
说明调用成功

但是使用这种方法来调用C++函数显然是不可行的,这个时候就需要extern关键字了,修改test.cpp如下:
test.cpp:
extern "C"
{
    int add(int a, int b);
}

int add(int a, int b)
{
    return a+b;
}
编译:
g++ -o test.o -c test.cpp
nm -s test.o
此时查看test.o的符号表就有add函数了,这时就可以通过add直接来调用该函数了,extern "C"的含义就是告诉编译器,下面的函数使用C风格来编译,
C语言编译时就不会修改函数名,因为没有重载,类,命名空间等这些概念,函数名是唯一的,而C++因为有类、命名空间、函数重载这些概念,所以函数名
可能是相同的,所以C++编译器会修改函数名,使得两个相同函数名的函数在调用时不会产生冲突。比如有两个类test1和test2,它们都有同名函数add,
这时C++编译器就会将test1中的add编译成类似xxtest1xaddxx这样的函数名,test2中的add会被编译成类似xxtest2xxaddxx的函数名,这样调用函数就不会冲突了。

猜你喜欢

转载自blog.csdn.net/u014783685/article/details/82983754