《__cplusplus修饰符的作用:C和CPP接口互相调用时候,编译没问题,链接提示未定义问题》
关于__cplusplus修饰符说明如下:
__cplusplus是cpp中的自定义宏,那么定义了这个宏的话表示这是一段cpp的代码,也就是说,上面的代码的含义是:如果这是一段cpp的代码,那么加入extern "C"{和}处理其中的代码。
要明白为何使用extern "C",还得从cpp中对函数的重载处理开始说起。在c++中,为了支持重载机制,在编译生成的汇编码中,要对函数的名字进行一些处理,加入比如函数的返回类型等等.而在C中,只是简单的函数名字而已,不会加入其他的信息.也就是说:C++和C对产生的函数名字的处理是不一样的. 目的就是主要实现C与C++的相互调用问题。
应用场景:
用gcc编译c和cpp混合在一起的头文件(g++编译场景会有点不一样)
led_ctrl.cpp
#include "led_ctrl.h" using namespace std; int led_ctrl(void *param, long unsigned int len) { return 0; } led_ctrl::led_ctrl() { }
led_ctrl.h
#ifndef __LED_CTRL_H__ #define __LED_CTRL_H__
// C++ 类定义(仅限 .cpp 文件使用) #ifdef __cplusplus class led_ctrl{ public: led_ctrl(); private: int fd; }; #endif // C 兼容的函数声明(供 .c 文件调用) #ifdef __cplusplus extern "C" { #endif int led_ctrl(void *param, long unsigned int len); #ifdef __cplusplus } #endif #endif
test.c
#include "led_ctrl.h" int main(void) { char buf[1] = {0}; led_ctrl(buf, 1); return 0; }
这样用gcc编译test.c才不会报错。
主要就是在cpp对应的.h中,分别对C++相关的定义和C的定义分别声明。
demo1:
创建一个test.cpp 和test1.cpp文件。
test.cpp
#include <stdio.h> extern void test(void); int main(void) { test(); return 0; }
test1.cpp
#include <stdio.h> void test(void) { printf("I am test \n"); }
然后g++ test.cpp test1.cpp,这样就没问题。因为2个文件都按照CPP的规则编译。
demo2:
现在把上面的test.cpp改成test.c。因为我们不确定调用test1.cpp的是c文件还是cpp文件。
gcc test.c test.cpp
test.c:(.text+0x9): undefined reference to `test'
这个时候就会提示test函数找不到。
解决方案:
test1.cpp
#include <stdio.h> #ifdef __cplusplus extern "C" { #endif void test(void) { printf("I am test \n"); } #ifdef __cplusplus } #endif
demo3:
如果再把test.c改成test.cpp,test1.cpp还是用demo2解决方案中的代码。
g++ test.cpp test1.cpp
test.cpp:(.text+0x9): undefined reference to `test()'
这是因为test1.cpp中的test函数是按照C的规则编译,而test.cpp中extern的test是按照cpp的编译,所以导致找不到。
解决方案:
test.cpp
#include <stdio.h> #ifdef __cplusplus extern "C" { #endif extern void test(void); #ifdef __cplusplus } #endif int main(void) { test(); return 0; }
浙公网安备 33010602011771号