首页 > 代码库 > extern "C" 的含义:????实现C++与C及其他语言的混合编程
extern "C" 的含义:????实现C++与C及其他语言的混合编程
C++中extern "C"的设立动机是实现C++与C及其他语言的混合编程。
对于函数void foo( int x, int y );该函数被C编译器编译后在符号库中的名字为_foo。而C++编译器则会产生像_foo_int_int之类的名字。
通常。在模块的头文件里对本模块提供给其他模块引用的函数和全局变量以keywordextern声明。
比如,假设模块B欲引用该模块A中定义的全局变量和函数时仅仅需包括模块A的头文件就可以。这样,模块B中调用模块A中的函数时,在编译阶段,模块B尽管找不到该函数。可是并不会报错。它会在连接阶段中从模块A编译生成的目标代码中找到此函数。
与extern相应的keyword是static。被它修饰的全局变量和函数仅仅能在本模块中使用。因此,一个函数或变量仅仅可能被本模块使用时,其不可能被extern “C”修饰。
被extern "C"修饰的变量和函数是依照C语言方式编译和连接的。
// 模块A头文件 moduleA.h
int foo( int x, int y );
在模块B中引用该函数:
// moduleB.cpp
#include "moduleA.h"
foo(2,3);
// moduleB.cpp
#include "moduleA.h"
foo(2,3);
实际上,在连接阶段。连接器会从模块A生成的目标文件moduleA.obj中寻找_foo_int_int这种符号!
加extern "C"声明后,模块A的头文件变为:
// 模块A头文件 moduleA.h
extern "C" int foo( int x, int y );
// 模块A头文件 moduleA.h
extern "C" int foo( int x, int y );
(1)模块A编译生成foo的目标代码时。没有对其名字进行特殊处理,採用了C语言的方式;
(2)连接器在为模块B的目标代码寻找foo(2,3)调用时。寻找的是未经改动的符号名_foo。
假设在模块A中函数声明了foo为extern "C"类型,而模块B中包括的是extern int foo( int x, int y ) 。则模块B找不到模块A中的函数;反之亦然。
在C语言的头文件里,对其外部函数仅仅能指定为extern类型。C语言中不支持extern "C"声明。在.c文件里包括了extern "C"时会出现编译语法错误。在C中引用C++语言中的函数和变量时。C++的头文件需加入extern "C",可是在C语言中不能直接引用声明了extern "C"的该头文件。应该仅将C文件里将C++中定义的extern "C"函数声明为extern类型。比如:
//C++头文件 a.h
extern "C" int foo( int x, int y );
extern "C" int foo( int x, int y );
//C++实现文件 a.cpp
#include "a.h"
int foo( int x, int y ){return x + y;}
#include "a.h"
int foo( int x, int y ){return x + y;}
/* C实现文件 b.c
这样会编译出错:#include "a.h" */
extern int foo( int x, int y );
int main( int argc, char* argv[] ){
这样会编译出错:#include "a.h" */
extern int foo( int x, int y );
int main( int argc, char* argv[] ){
}
extern "C" 的含义:????实现C++与C及其他语言的混合编程
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。