C/C++混合编程

来源:互联网 发布:javascript写网页 编辑:程序博客网 时间:2024/06/05 20:29

C/C++混合编程

C++ 调用 C 的步骤比较简单,只需要将C的代码使用extern “C”包含声明即可

cpp:    int main()    {        c_fun_xxx();    }c:    extern "C" {        int c_fun_cxx();    }

通过extern “C“的声明,编译器会将声明部分按照C的语法进行编译

C调用C++

C调用C++则比较繁琐,需要谨记一点是C的代码中决不能出现关于C++的任何语法,包含头文件中也不可以。
所以通常的做法是将C++进行一层封装

举个例子:
首先 在cxx.h中 实现一个类的声明,类包含一个成员函数

class cxx {    public:        int cxx_call();}

在cxx.cpp中实现成员函数

int cxx::cxx_call(){    cout << "call function cxx_call" << endl;}

以上实现的是C++的功能实现,要被C代码调用,还需要对功能实现代码进行一层封装
在cxx_impl.cpp中实现它

#include "cxx.h"int c_call_cxx(void **ptr){    (cxx *)p = new cxx();    p->cxx_call();    (cxx *)*ptr = p;    return 0;}

并在头文件cxx_impl.h中声明这个c接口

#indef __cplusplusextern "C" {#endifint c_call_cxx(void **ptr);#ifdef __cplusplus}#endif
  1. 传入空指针是为了做类型的传递,外部的C代码不能直接访问cxx这个类,但所幸指针都是同样的大小,所以传入空指针,传入后自行做类型转换
  2. cxx_impl.h中的ifdef是为了在以c++编译器编译时,让c函数int c_call_cxx(void *ptr)声明被extern “C” 声明
  3. 传入二级指针是为了返回申请的类的地址,方便继续调用一个类内的其他成员函数 避免每次调用不同的成员函数都申请一个类

在test.c中调用:

int main(){    void *ctx;    c_call_cxx(&ctx);}

注意:C调用C++时 需要把C的编译器也设为C++所用的编译器 这点在vs下是默认的 不需要修改
但在linux下,修手动指定
例如使用cmake
SET(CMAKE_C_CPMPILER g++)

我写了一个参考的C调用C++实现的内存管理链表的实现
linux下 cmake 建立的工程,可供调用的参考 稍后完善些再放上来
mem_collector

原创粉丝点击