C和C++混合编程FAQ
2016-04-25 22:00
423 查看
如何在C++
中调用C函数?
仅仅只需要在你的C++代码中将要调用的C函数使用extern进行声明即可,代码如下://C++ code extern "C" void f(int); //方式一 extern "C" { //方式二 int g(double); double h(); } void code(int i,double d) { f(i); int ii = g(d); double dd = h(); //........ }
在你的C代码中对上述几个调用的函数就行定义即可,定义如下:
// C code void f(int i) { /*....*/ } int g(double d) { /*....*/ } double h() { /*....*/ }
如何在C中调用C++
的函数?
在C++中定义的函数,需要显示的使用extern进行声明,目的是让编译器不对其进行名称mangle,代码如下:// C++ code: extern "C" void f(int); void f(int i) { // ... }
将上面的代码编译成动态库,然后交由C动态的去调用。下面是在C中如何去调用
/* C code: */ void f(int); void cc(int i) { f(i); /* ... */ }
C调用C++的非成员函数就用如上的方式即可完成,那么C如何去调用C++的类成员函数呢?代码如下:
#include <iostream> using namespace std; class C { public: virtual double f(int data) { cout << "Hello World" << endl; } }; extern "C" C* getC() { return new C(); } extern "C" void delC(C *data) { delete data; } extern "C" double call_C_f(C* p,int i) { return p->f(i); }
上面定义了一个class C,在这个class C中有我们需要调用的f函数,为了可以调用这个f函数,我们需要提供一个call_c_f这个函数。在这个函数中通过一个具体的对象指针来调用f函数,为了得到对象指针我们提供了getC函数来实例化一个class C,通过指针传递给C函数来使用。下面是C中调用C++的方法:
#include <stdio.h> struct C; /* C code: */ double call_C_f(struct C *p, int i); struct C *getC(); void delC(); void ccc(struct C* p, int i) { double d = call_C_f(p,i); /* ... */ } int main() { struct C * data = getC(); ccc(data,10); delC(data); }
首先是对call_C_f,getC,delC三个函数的一个声明,然后就是前向声明class C,因为C中没有class的概念,因此转而使用了struct。首先通过getC得到类C的对象指针,然后传递给call_C_f即可,在使用完成后调用delC释放对象指针。
到此为止C可以调用C++的非成员函数和成员函数了,那么如果去调用C++中的重载函数呢,这个比较简单,代码如下:
// C++ code: void f(int); void f(double); extern "C" void f_i(int i) { f(i); } extern "C" void f_d(double d) { f(d); }
其实就是给每一个重载的实列都包裹一下即可。就跟C调用C++的非成员函数一个样子。
如何在C++
的代码中包含标准C的头文件?
在C++的代码中去包含标准C的头文件基本上不需要做什么特殊的改变,直接#include某个标准库文件即可,比如
stdio.h,同样你可以使用
cstdio。代码如下:
/* This is C code that I'm compiling using a C++ compiler */ #include <stdio.h> /* Nothing unusual in #include line */ int main() { printf("Hello world\n"); /* Nothing unusual in the call either */ // ... }
说白了
stdio.h和
cstdio的区别就是一个C版本的,一个是C++版本的,其中C++版本的就是将
stdio.h中的内容加入到了C++的std命名空间中,下面的例子中包含了
cstdio并引用了std命名空间中的
printf函数
// This is C++ code #include <cstdio> // Nothing unusual in #include line int main() { std::printf("Hello world\n"); // Nothing unusual in the call either // ... }
如何在C++
代码中包含C非标准库头文件?
如果你要在你的C++代码中包含一些C的非标准库头文件,那么你需要使用extern "C"声明,告诉C++编译器头文件中包含的是C函数。
// This is C++ code extern "C" { // Get declaration for f(int i, char c, float x) #include "my-C-code.h" } int main() { f(7, 'x', 3.14); // Note: nothing unusual in the call // ... }
如何修改C的头文件让其可以直接在C++
的代码中#include
?
在C++中为了包含C的非标准库的头文件我们需要将头文件的包含语句放在extern "C"声明中,你一定很奇怪为什么C标准库不需要这样呢?因为C标准库中做了一些手脚,不信你可以看看
stdio.h的源码,你会发现在这个头文件的开始有一个
__BEGIN_DECLS,结尾有一个
__END_DECLS。这两个宏的定义如下:
#if defined(__cplusplus) #define __BEGIN_DECLS extern "C" { #define __END_DECLS } #else #define __BEGIN_DECLS #define __END_DECLS #endif
哈哈,看到这里我相信大家应该明白了吧,如果
stdio.h被包含在C++的代码中那么
__BEGIN_DECLS和
__END_DECLS就够成了一个
extern "C" {}将整个头文件包含在里面了,就等同于
extern "C" {#include <stdio.h>}。那么如何改造我们的头文件让其可以直接
#include到C++的代码中呢?
Setp1: 将下面的这行放在头文件的开始处,通过判断是否有
__cpluscplus判定是被包含在C代码中,还是C++代码中
#ifdef __cplusplus extern "C" { #endif
Setp2: 将下面的代码放在头文件的最下面
#ifdef __cpluscplus } #endif
到此为止你可以直接将一个非标准库的头文件
#include到你的C++代码中了。
如何将C++
中的类的对象传递给C函数?
下面是一个完整的示列。/* This header can be read by both C and C++ compilers */
#ifndef FRED_H
#define FRED_H
#ifdef __cplusplus
class Fred {
public:
Fred();
void wilma(int);
private:
int a_;
};
#else
typedef
struct Fred
Fred;
#endif
#ifdef __cplusplus extern "C" { #endif
#if defined(__STDC__) || defined(__cplusplus)
extern void c_function(Fred*); /* ANSI C prototypes */
extern Fred* cplusplus_callback_function(Fred*);
#endif
#ifdef __cplusplus
}
#endif
#endif /*FRED_H*/
上面这个头文件可以被C和C++包含,当被C包含的时候就是一个
Fred类和C风格的
c_function和
cplusplus_callback_function的声明。
// This is C++ code #include "fred.h" Fred::Fred() : a_(0) { } void Fred::wilma(int a) { } Fred* cplusplus_callback_function(Fred* fred) { fred->wilma(123); return fred; }
这是C++的Fred的类实现.
/* This is C code */ #include "fred.h" void c_function(Fred* fred) { cplusplus_callback_function(fred); }
这是一段C代码,包含了
fred.h,因此有
struct Fred声明,参考
如何在C中调用C++的函数?一节。因为C中没有Class所以只能用struct来表示,并且Class在大多数情况下其内存布局都和C中的struct不一样,因此这里只能选择使用指针。
// This is C++ code #include "fred.h" int main() { Fred fred; c_function(&fred); // ... }
这是一段C++代码,同样包含了
fred.h,因此有了
class Fread声明,
fred.c是其定义, 同时还包含了C风格的
c_funcion和
cplusplus_callback_function声明,参考
如何在C++中调用C函数?一节
Reference
How to mix C and C++相关文章推荐
- 一位高手整理的IIS FAQ
- jQuery实现默认是闭合的FAQ展开效果菜单
- 深入Android开发FAQ的详解
- 深入理解C/C++混合编程
- C和C++混合编程问题
- python和C语言混合编程实例
- Swift和C语言混合编程教程
- Swift、Objective-C、Cocoa混合编程设置指南
- 在Swift中使用Objective-C编写类、继承Objective-C类
- 在一个项目中同时使用Swift和Objective-C代码混合编程的方法
- MOSA 4600 Plus IP PBX FAQ(应用常见知识点-故障排除)
- MOSA 4600 Plus IP PBX FAQ(应用常见知识点-故障排除)(2)
- MOSA 4600 Plus IP PBX FAQ(应用常见知识点-操作使用)
- 浅谈C++与Java混合编程
- matlab与c/c++混合编程
- matlab与c/c++混合编程——c/c++调用matlab
- 关于栈、堆、静态变量区的访问效率
- 关于指针定义的一些问题
- 进制转换并打印
- 函数指针