您的位置:首页 > 运维架构 > Linux

c调用c++动态库的实现和注意事项(linux g++)

2017-11-09 17:18 246 查看
码工声明:本人也在学习,下面有些话是网上摘抄的---吐血的CSDN,图片不支持拷贝,不支持拷贝为啥还要正常显示,导致很多贴图都没有了

只介绍c调用c++过程中我所遇到的一些低级错误

1.先介绍一下c和c++编译

如果是已经用c++编译器编译好的so文件,使用c语言直接引用是会报错的,原因是c和c++的编译器在处理函数名称时规则不同,相同的函数比如hello(int i),c语言可能会处理成hello或者_hello,具体估计与编译器有关,但c++的话由于存在重载功能,会将参数类型等信息全部包含进去,一遍唯一定位某一函数,所以c++可能命名为_Z10helloP9int,这样即使存在hello函数名称相同的,但由于参数部分的名字不同,也可以唯一定位到需要的函数。呵呵,c++我不懂,班门弄斧了,啰嗦了一句。

hello.cpp编译生成libhello.so

相同的函数下面是用c++编译的结果

“图片被CSDN吃了”

下面是通过extern "C" 选项编译的,代码如图所示

“图片被CSDN吃了”

hello.h代码

“图片被CSDN吃了”

同样hello.h中的声明也要用extern "C",否则会报错,错误如下,应该是相同函数定义规则不同冲突了

“图片被CSDN吃了”

编译过后的nm查看函数名如下

“图片被CSDN吃了”

可以看出函数hello与代码名称相同,且不带参数

2、extern "C",注意c一定要大写,小写会报错;__cplusplus 前面是两个下划线

“"C"表示的是一种链接约定,只是因C和C++语言之间的密切关系而在它们之间更多的应用而已。实际上Fortran和汇编语言也常常使用,因为它们也正好符合C实现的约定。
extern "C"指令描述的是一种链接约定,它并不影响调用函数的定义,即时做了该声明,对函数类型的检查和参数转换仍要遵循C++的标准,而不是C”

此外还有extern "FORTRAN"

还是以hello word为例,假设用cpp且不加extern "C"来编译,那么生成的libhello.so是按照c++的约定进行编译的,如果c要调用则必须使用一个中间的过度,使得编译生成的函数按照c语言的约定编译,这样在调用时才能找到

中间文件定义为helloInf.cpp,不截图了,手敲吧

#include "hello.h"

#ifdef   __cplusplus

   extern "C" {

#endif

void helloInf()

{

   hello(1);



#ifdef __cplusplus

   }

#endif

同理如果helloInf.h里面的声明也要加上#ifdef __cplusplus.....

编译生成的libhelloInf.so,用main.c就可以直接调用了

main.c

#include "helloInf"

void main(void)

{

helloInf();

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: