链接指示:extern 'C'
1.声明非C++函数
链接指示有两种形式:单个的和复合的。链接指示不能出现在类定义或函数定义的内部,它必须出现在函数的第一次声明上。
// single statement linkage directive
extern "C" size_t strlen(const char *);
// compound statement linkage directive
extern "C" {
int strcmp(const char *, const char *);
char *strcat(char *, const char *);
}
2.链接指示与头文件
可以将多重声明形式应用于整个头文件
// compound statement linkage directive
extern "C" {
#include <string.h>
}
链接指示可以嵌套,所以,如果头文件包含了带链接指示的函数,该函数的链接不受影响
3.导入C++函数到其他语言
通过对函数定义使用链接指示,使得用其他语言编写的程序可以使用C++函数:
// the calc function can be called from C programs
extern "C" double calc(double dparm) { /* ... ... */ }
当编译器为该函数产生代码的时候,它将产生适合于指定语言的代码。
4.链接指示支持的语言
要求编译器支持对C语言的链接指示。编译器可以为其他语言提供链接说明。例如:extern “Ada”、extern “FORTRAN”等。 对链接到C的预处理器支持: 有时需要在C和C++中编译同一源文件。当编译C++时,自动定义预处理器名字__cplusplus,所以可以根据是否正在编译C++有条件地包含代码。
#ifdef __cplusplus
// ok : we're compiling C++
extern "C"
#endif
int strcmp(const char *, const char *);
5.重载函数与链接指示
链接指示与函数重载之间的相互作用依赖于目标语言。如果语言支持重载函数,则为该语言实现链接指示的编译很可能也支持C++的这些函数重载。 C++保证支持的唯一语言是C,C语言不支持函数重载,所以,不应该对下面的情况感到惊讶:在一组重载函数中只能为一个C函数指定链接指示。用带给定名字的C链接声明多于一个函数是错误的:
// error : two extern "C" functions in set of overloaded functions
extern "C" void print(const char *);
extern "C" void print(int);
在C++程序中,重载C函数很常见,但是,重载集合中的其他函数必须都是C++函数:
class SmallInt { /* */ };
// the C function can be called from C and C++ programs
// the C++ functions overloaded that function and are callable from C++
extern "C" double calc(double);
extern SmallInt calc(const SmallInt &);
可以从C程序和C++程序调用calc的C版本。其余函数是带类型形参的C++函数,只能从C++程序调用。声明的次序不重要。
6.extern “C” 函数指针
编写函数所用的语言是函数类型的一部分。为了声明用其他程序设计语言编写的函数的指针,必须使用链接指示:
// pf points to a C function returning void taking an int
extern "C" void (*pf)(int);
使用pf调用函数的时候,假定该调用是一个C函数调用而编译该函数。 note:C函数的指针与C++函数的指针具有不同的类型,不能将C函数的指针初始化或赋值为C++函数的指针(反之亦然) 存在这种不匹配的时候,会给出编译的错误:
void (*pf1)(int); // points to a C++ function
extern "C" void (*pf2)(int); // points to a C funtion
pf1 = pf2; // error: pf1 and pf2 have different types
7.应用于整个声明的链接指示
使用链接指示的时候,它应用于函数和任何函数指针,作为返回类型或形参类型使用:
// f1 is a C function; its parameter is a pointer to a C function
extern "C" void f1(void(*)(int));
// FC is a pointer to C function
extern "C" typedef void FC (int);
// f2 is a C++ function with a parameter that is a pointer to a C function
void f2(FC *);