可以在C++中使用C的已编译好的函数模块,在c++中用到c语言写的函数,声明DLL中经常看到,避免C++ name mangling,主要用于动态链接库,使得导出函数名称与C语言规则一致(不改变),方便不同的编译器甚至是不同的开发语言调用。
extern "C"是告诉C++编译器以C Linkage方式编译,也就是抑制C++的name mangling机制。
例如:
void Test(void);
extern "C" void Test(void) 则和C编译器一样为_Test。
一、修饰名(Decorated Name)
C/C++程序中的函数在内部是通过修饰名来标识的。修饰名是在函数定义或原型编译阶段由编译器创建字符串。当你在LINK等工具中要指定一个函数名时,会用到修饰名。
1、使用修饰名:
大多数情况下,你不必知道函数的修饰名是什么。连接器等工具通常都能处理函数未修饰的名字。然而,在有些情况下,你可能需要指定函数的修饰名。对于C++重载函数和特定的成员函数(如:构造函数和析构数),必须指定这些函数的修饰名,以便连接器等工具能够匹配名字。同时,也必须在那些引用c或c++函数名的汇编源文件中使用修饰名。
2、查看修饰名:
如果你编译了一个源文件,该源文件中包含了函数定义或原型,你可以获得函数的修饰名形式。
(1)用编译器列表(compiler listing)来查看:
(2)使用DUMPBIN工具来查看:
在.OBJ或.LIB上运行 DUMPBIN,使用/SYMBOLS选项。在输出中查找未经修饰的函数定义。后面跟着的就是经过修饰的函数名,用圆括号括起来的。
二、替代连接说明:
如果在c++中编写一个程序需要用到c的库,那该如何?
如果这样声明一个c函数:void f(int a,char b);
c++编译器就会将这个名字变成相应的修饰名,
然而,c编译器编译的库的内部函数名(连接器使用)是完全不同的。这样,当c++连接器连接c的函数库时,将会产生内部使用函数不匹配。
故c++中提供了一个通过重载extern关键字来实现的替代连接说明(alternate linkage specification。
extern后跟一个字符串来指定想声明的函数的连接类型,后面是函数声明,
比如:extern "C" void f(int a,char b);
这样,就是告诉编译器是c连接,这样就不会转换函数名了。此例中,编译后的内部函数名是_f。