extern “C”

extern "C"

一句话概括 extern "C" 的作用:告诉 C++ 编译器,编译某段代码时不要进行名字重整,以此达到 C++ 中调用 C 函数,或者 C 中调用 C++ 函数的目的;
之所以 C++ 会有名字重整,是因为 C++ 为了实现重载等特性,需要在编译期把函数名重整,针对不同的参数调用识别不同的函数名;
注意:extern "C" 是 C++ 为了兼容 C 代码才加上的东西,只在 C++ 里才有, C 语言里面是没有 extern "C" 的;
C模块: 不会有名字重整,编译后,声明的函数名都没变: void foo(void) --> foo
C++模块: 存在名字重整:编译后,声明的函数名会改变: void foo(void) --> xxxfooxxx
C 模块中调用 C++ 函数: 两个模块分别编译,链接期 C 模块按照未重整的名字 foo 去 C++ 模块的 .obj 文件里查找函数,会失败!
C++ 模块中调用 C 函数: 两个模块分别编译,链接期 C++ 模块按照重整后的名字 xxxfooxxx 去 C 模块的 .obj 文件里查找函数,会失败!
C++ 为了兼容 C 代码,加上了 extern "C"。



C++ 中调用 C 模块的函数:
main.cpp:
extern "C"{
#include "CClass.h"
};
int _tmain(int argc, _TCHAR* argv[])
{
    foo();
    return 0;
}
CClass.h 是C模块的头文件,以上代码告诉编译器, CClass.h 里面的函数声明,不要进行名字重整。这样 main.cpp 在编译的时候, CClass.h 里面的函数不会进行名字重整,C++ 模块可以
从中找到正确的函数;
如果不加 extern "C" 就会出现链接错误:error LNK2001: 无法解析的外部符号 "void __cdecl foo(void)" (?foo@@YAXXZ)


C++ 提供接口给 C 模块调用:
cppclass.h:
extern "C" void foo(void);
extern "C" void func(int);

main.c
extern void foo(void);
extern void func(int);
cppclass.h 是 C++ 模块的头文件,以上代码告诉编译器,foo,func 这两个函数,不要jinx那个名字重整。这样 cppclass 在编译的时候, foo,func 不会被重整, C 模块可以从中找到正确
的函数。
这种情况下,因为在 C 中 extern "C" 是不合法的,所以不能直接在 main.c 中 #include "cppclass.h", 而是通过 extern void foo(void); 的方式声明 foo 这个函数,链接的时候会从 
cppclass.obj 里找到它。


DLL 的头文件中使用 extern "C":
在 DLL 中,如果我们用 C++ 编译器编译它而且没有加上 extern "C",那么就有可能这个 dll 不能被 C 模块调用,因为其中的函数被重整了。
为了让这个 dll 能够被 C 模块调用,我们需要为它加上 extern "C",下面的头文件可以被 C 模块或 C++ 模块包含使用。
// MyCFuncs.h
#ifdef __cplusplus
extern "C" {  // only need to export C interface if
              // used by C++ source code
#endif

__declspec( dllimport ) void MyCFunc();
__declspec( dllimport ) void AnotherCFunc();

#ifdef __cplusplus
}
#endif

 

参考链接:

http://www.cnblogs.com/graphics/archive/2010/12/24/1916343.html

posted on 2014-08-15 11:29  zuibunan  阅读(669)  评论(0编辑  收藏  举报

导航