【 声明:版权所有,欢迎转载,请勿用于商业用途。 】
作为系统工程师,平时用c可能多一些。这两天因为工作的原因,了解了linux上面cpp的编写方法。很多时候,cpp对编写者的要求比较高,在市场上面的应聘者也比较少,所以大多数公司都是选择c和脚本作为开发语言。但是有一些项目,比如机器学习、ros系统,要是用上它,那么cpp是绕不过去的。下面,我就简单说一下c&cpp相互调用的事情。
1、在cpp下面,不同的函数可以用同一个函数名字,
int add() {
return 0;
}
int add(int a){
return a;
}
2、看一下反汇编出来是什么样的,
121 000000000040052d <_Z3addv>:
122
123 int add() {
124 40052d: 55 push %rbp
125 40052e: 48 89 e5 mov %rsp,%rbp
126
127 return 0;
128 400531: b8 00 00 00 00 mov $0x0,%eax
129 }
130 400536: 5d pop %rbp
131 400537: c3 retq
132
133 0000000000400538 <_Z3addi>:
134
135 int add(int a){
136 400538: 55 push %rbp
137 400539: 48 89 e5 mov %rsp,%rbp
138 40053c: 89 7d fc mov %edi,-0x4(%rbp)
139
140 return a;
141 40053f: 8b 45 fc mov -0x4(%rbp),%eax
142 }
143 400542: 5d pop %rbp
144 400543: c3 retq
145
3、从代码可以看出来其实g++编译器对两个函数做了修改,我们看如果用extern "c"来解决会怎么样
$ g++ hello.cpp -g -o hello
hello.cpp:5:15: error: declaration of C function ‘int add(int)’ conflicts with
int add(int a);
^
hello.cpp:4:6: error: previous declaration ‘int add()’ here
int add();
4、从消息来看,说明在extern的情况下其实只能有一个add。没关系,我们可以删除一个add,
127 int add(int a){
128 40052d: 55 push %rbp
129 40052e: 48 89 e5 mov %rsp,%rbp
130 400531: 89 7d fc mov %edi,-0x4(%rbp)
131
132 return a;
133 400534: 8b 45 fc mov -0x4(%rbp),%eax
134 }
135 400537: 5d pop %rbp
136 400538: c3 retq
137
5、实验说明了显式调用函数的时候,最好添加extern "C"。
如果cpp调用c库,那么c库中header头文件中对函数原型的声明一定要有extern "C"
如果是c调用cpp,那么cpp库中header头文件中函数原型的部分一定要有extern "C"