徐州手机网站制作,怎么做企业招聘网站,网络营销工具主要类型有,node 网站开发extern “C”的作用详解 extern C的主要作用就是为了能够正确实现C代码调用其他C语言代码。加上extern C后#xff0c;会指示编译器这部分代码按C语言的进行编译#xff0c;而不是C的。由于C支持函数重载#xff0c;因此编译器编译函数的过程中会将…extern “C”的作用详解 extern C的主要作用就是为了能够正确实现C代码调用其他C语言代码。加上extern C后会指示编译器这部分代码按C语言的进行编译而不是C的。由于C支持函数重载因此编译器编译函数的过程中会将函数的参数类型也加到编译后的代码中而不仅仅是函数名而C语言并不支持函数重载因此编译C语言代码的函数时不会带上函数的参数类型一般之包括函数名。这个功能十分有用处因为在C出现以前很多代码都是C语言写的而且很底层的库也是C语言写的为了更好的支持原来的C代码和已经写好的C语言库需要在C中尽可能的支持C而extern “C就是其中的一个策略。 这个功能主要用在下面的情况 1、C代码调用C语言代码 2、在C的头文件中使用 3、在多个人协同开发时可能有的人比较擅长C语言而有的人擅长C这样的情况下也会有用到 给出一个我设计的例子 moduleA、moduleB两个模块B调用A中的代码其中A是用C语言实现的而B是利用C实现的下面给出一种实现方法 //moduleA头文件 #ifndef __MODULE_A_H //对于模块A来说这个宏是为了防止头文件的重复引用 #define __MODULE_A_H int fun(int, int); #endif //moduleA实现文件moduleA.C //模块A的实现部分并没有改变 #includemoduleA” int fun(int a, int b) { return ab; } //moduleB头文件 #idndef __MODULE_B_H //很明显这一部分也是为了防止重复引用 #define __MODULE_B_H #ifdef __cplusplus //而这一部分就是告诉编译器如果定义了__cplusplus(即如果是cpp文件 extern “C”{ //因为cpp文件默认定义了该宏),则采用C语言方式进行编译 #includemoduleA.h #endif … //其他代码 #ifdef __cplusplus } #endif #endif //moduleB实现文件 moduleB.cpp //B模块的实现也没有改变只是头文件的设计变化了 #includemoduleB.h int main() { coutfun(2,3)endl; } 下面是详细的介绍 由于C、C编译器对函数的编译处理是不完全相同的尤其对于C来说支持函数的重载编译后的函数一般是以函数名和形参类型来命名的。 例如函数void fun(int, int)编译后的可能是不同编译器结果不同_fun_int_int(不同编译器可能不同但都采用了类似的机制用函数名和参数类型来命名编译后的函数名)而C语言没有类似的重载机制一般是利用函数名来指明编译后的函数名的对应上面的函数可能会是_fun这样的名字。 看下面的一个面试题为什么标准头文件都有类似的结构 #ifndef __INCvxWorksh /防止该头文件被重复引用/ #define __INCvxWorksh #ifdef __cplusplus //告诉编译器这部分代码按C语言的格式进行编译而不是C的 extern “C”{ #endif /…/ #ifdef __cplusplus } #endif #endif /end of __INCvxWorksh/ 分析
显然头文件中编译宏#ifndef __INCvxWorksh 、#define __INCvxWorksh、#endif即上面代码中的蓝色部分的作用是为了防止该头文件被重复引用
那么
#ifdef __cplusplus (其中__cplusplus是cpp中自定义的一个宏) extern “C”{ #endif #ifdef __cplusplus } #endif 的作用是什么呢 extern C包含双重含义从字面上可以知道首先被它修饰的目标是extern的其次被它修饰的目标代码是C的。
被extern C限定的函数或变量是extern类型的
extern是C/C语言中表明函数和全局变量的作用范围的关键字该关键字告诉编译器其申明的函数和变量可以在本模块或其他模块中使用。 记住下面的语句 extern int a; 仅仅是一个变量的声明其并不是在定义变量a并未为a分配空间。变量a在所有模块中作为一种全局变量只能被定义一次否则会出错。 通常来说在模块的头文件中对本模块提供给其他模块引用的函数和全局变量以关键字extern生命。例如如果模块B要引用模块A中定义的全局变量和函数时只需包含模块A的头文件即可。这样模块B中调用模块A中的函数时在编译阶段模块B虽然找不到该函数但并不会报错它会在链接阶段从模块A编译生成的目标代码中找到该函数。 extern对应的关键字是staticstatic表明变量或者函数只能在本模块中使用因此被static修饰的变量或者函数不可能被extern C修饰。
被extern C修饰的变量和函数是按照C语言方式进行编译和链接的这点很重要
上面也提到过由于C支持函数重载而C语言不支持因此函数被C编译后在符号库中的名字是与C语言不同的C编译后的函数需要加上参数的类型才能唯一标定重载后的函数而加上extern “C后是为了向编译器指明这段代码按照C语言的方式进行编译 未加extern “C声明时的链接方式 //模块A头文件 moduleA.h #idndef _MODULE_A_H #define _MODULE_A_H int foo(int x, int y); #endif 在模块B中调用该函数 //模块B实现文件 moduleB.cpp #includemoduleA.h” foo(2,3); 实际上在链接阶段连接器会从模块A生成的目标文件moduleA.obj中找_foo_int_int这样的符号显然这是不可能找到的因为foo()函数被编译成了_foo的符号因此会出现链接错误。 常见的做法可以参考下面的一个实现 moduleA、moduleB两个模块B调用A中的代码其中A是用C语言实现的而B是利用C实现的下面给出一种实现方法 //moduleA头文件 #ifndef __MODULE_A_H //对于模块A来说这个宏是为了防止头文件的重复引用 #define __MODULE_A_H int fun(int, int); #endif //moduleA实现文件moduleA.C //模块A的实现部分并没有改变 #includemoduleA” int fun(int a, int b) { return ab; } //moduleB头文件 #idndef __MODULE_B_H //很明显这一部分也是为了防止重复引用 #define __MODULE_B_H #ifdef __cplusplus //而这一部分就是告诉编译器如果定义了__cplusplus(即如果是cpp文件 extern “C”{ //因为cpp文件默认定义了该宏),则采用C语言方式进行编译 #includemoduleA.h #endif … //其他代码 #ifdef __cplusplus } #endif #endif //moduleB实现文件 moduleB.cpp //B模块的实现也没有改变只是头文件的设计变化了 #includemoduleB.h int main() { coutfun(2,3)endl; } extern C的使用要点
可以是单一语句 extern “C” double sqrt(double);可以是复合语句, 相当于复合语句中的声明都加了extern “C” extern “C” { double sqrt(double); int min(int, int); } 3.可以包含头文件相当于头文件中的声明都加了extern “C” extern “C” { i nclude }不可以将extern “C” 添加在函数内部如果函数有多个声明可以都加extern “C”, 也可以只出现在第一次声明中后面的声明会接受第一个链接指示符的规则。除extern “C”, 还有extern “FORTRAN” 等。 参考文章 extern C使用 extern c的作用【转】_看雪… extern C使用要点 http://blog.chinaunix.net/u/29619/showart_230148.html http://blog.csdn.net/weiqubo/archive/2009/10/16/4681813.aspx http://hi.baidu.com/sundl2268/blog/item/4969453d2258bae53c6d970a.html“I find that the harder i workthe more luck i seem to have”