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();
}
只介绍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();
}
相关文章推荐
- Linux下关于动态库调用动态库及编译需要注意的事项
- C++调用C#生成的DLL实现及注意事项
- (转)如何在linux C/C++语言中调用 sqlite 的函数接口来实现对数据库的管理
- C#中调用C++写的DLL注意事项
- 调用 动态库 实现插件(windows & linux)
- 使用C++实现JNI接口需要注意的事项
- linux0.11中的fork实现和一些注意事项
- linux用c++调用动态库
- Linux下显示加载动态库注意事项
- linux下使用jni实现c++调用java程序(4)DestroyJavaVM出现错误
- Linux下C/C++开发工具注意事项
- linux下使用jni实现c++调用java程序(5)参考资料总结
- .NET工程中以 C 和 C++ 两种方式编译时,函数调用注意事项
- linux下使用jni实现c++调用java程序(1)准备工作
- linux下C++控制台输出(如printf)注意事项
- 在Linux系统上实现虚拟主机的注意事项
- linux的ubuntu上如何编译C和C++代码写的动态库,以及调用执行
- Android开发 调用照相机实现代码和注意事项
- C++ 二叉树的实现以及指针使用注意事项
- java程序调用C、C++动态库的几种实现方式,即JNI的应用方式