C 程序与 C++ 程序之间的相互调用
程序员文章站
2022-07-05 11:13:07
因为 C 编译器编译函数时不带参数的类型信息,只包含函数的符号名字。如 void foo( int x ) , C 编译器会将此函数编译成类似 _foo 的符号,C 链接器只要找到了调用函数的符号,就会认为链接成功。而 C++ 编译器为了实现函数重载,会在编译时带上函数的参数信息。如它可以把上面的函 ......
因为 C 编译器编译函数时不带参数的类型信息,只包含函数的符号名字。如 void foo( int x ) , C 编译器会将此函数编译成类似 _foo 的符号,C 链接器只要找到了调用函数的符号,就会认为链接成功。而 C++ 编译器为了实现函数重载,会在编译时带上函数的参数信息。如它可以把上面的函数编译成类似于 _foo_int 这样的符号。
所以在 C++ 与 C 相互调用时,要用 extern "C" 加以声明。
下面用两个示例实现它们之间的相互调用(没有优化代码,只是起示例作用)。
C++ 调用 C 函数
/* cfile.c */ #include <stdio.h> void C_Func() { puts("Hello, I'm C_Func"); }
/* cppfile.cpp */ #include <iostream> extern "C" void C_Func(void); int main() { C_Func(); system("pause"); return 0; }
C 调用 C++ 内类的成员函数
/* cppfile.cpp */ #include <iostream> #include "cpphfile.h" using namespace std; void Myclass::print() { cout << "Hello, I'm print function." << endl; }
/* cpphfile.h */ #ifndef _CPPCLASS_H__ #define _CPPCLASS_H__ class Myclass{ public: void print(); }; #endif
/* wrapper.cpp 这个文件实现调用 C++ 的接口*/ #include "cpphfile.h" extern "C" { struct wrapper_class{ Myclass w_class; }; struct wrapper_class* get_object() { return new struct wrapper_class; } void call_cpp_print(struct wrapper_class* p) { p->w_class.print(); } }
/* cfile.c */ #include <stdio.h> struct wrapper_class *test; int main() { /* 创建对象 */ test = get_object(); /* 调用 C++ 函数 */ call_cpp_print(test); system("pause"); }
小总结
extern "C" 应该只能在 CPP 文件或被引入到 CPP 中的头文件内声明。
通常应该这样使用 extern "C":
#ifdef __cplusplus extern "C" { #endif /* your text */ #ifdef __cplusplus } #endif
C++ 编译器中已经定义了 __cplusplus 这个宏。
上一篇: C#特性
下一篇: C# 利用AForge进行摄像头信息采集