在C++程序中调用其他语言编写的函数,例如C语言。
要求有权访问该语言的编译器,并且该编译器与当前C++编译器兼容。
声明非C++函数
- 两种形式:单语句、复合语句。
- 链接指示不能出现在类定义或函数定义内部。
- 非C++函数的每个声明中都必须具有相同的链接指示。
1
2
3
4
5
6
7
8// 单语句链接指示
extern "C" size_t strlen(const char *);
// 复合语句链接指示
extern "C" {
int strcmp(const char *, const char *);
char *strcat(char *, const char *);
}
链接指示与头文件
采用复合声明的形式。
1
2
3extern "C" {
}头文件中的所有普通函数声明都被认为是由链接指示的语言编写的。
- 链接指示可以嵌套,如果头文件包含自带链接指示的函数,那么该函数的链接不受影响。
导出C++函数到其他语言
- 通过使用链接指示对函数进行定义:
1
extern "C" double calc(double dparm) { /* ... */ }
指向 extern “C” 函数的指针
编写函数所用的语言是函数类型的一部分。
因此,对于使用链接指示定义的函数而言,它的每个声明中都必须具有相同的链接指示。并且,指向函数的指针必须与函数本身使用相同的链接指示。1
2
3void (*pf1) (int); // 指向一个C++函数
extern "C" void (*pf2) (int); // 指向一个C函数
pf1 = pf2; // 错误:pf1与pf2的类型不同链接指示不仅对函数有效,而且对作为返回类型或形参类型的函数指针也有效。
1
2
3
4
5
6// f是一个C函数,参数是一个指向C函数的指针
// 调用f时,必须传入一个C函数的名字或者指向C函数的指针。
extern "C" void f(void (*) (int));
// 函数名代表某个函数的入口地址(常量)
// 函数指针相当于变量,可以存放所有该类型函数的入口地址因为链接指示同时作用于声明语句中的所有函数(指针),
所以如果要给C++函数传入一个指向C函数的指针,则必须使用类型别名。1
2
3
4// FC为函数指针类型,指向一个C函数
extern "C" typedef void (*FC)(int);
// f2是一个C++函数,形参为一个指向C函数的指针
void f2(FC);
链接指示与重载函数
- 链接指示与重载函数的相互作用依赖于目标语言。
C语言不支持重载,故一个C链接指示只能用于说明一组重载函数中的一个。
1
2
3// 错误:两个 extern "C" 函数名相同
extern "C" void print(const char *);
extern "C" void print(int);如果一组重载函数中有一个是C函数(可在C或C++中被调用),则其余的都必须为C++函数(只能在C++中被调用)