术语“链接规范”指链接用不同语言编写的函数(或程序)的协议。 下列调用约定将受影响:
名称是否区分大小写。
名称的修饰。 在 C 中,编译器将使用下划线作为名称的前缀。 这通常称为“修饰”。在 C++ 中,名称修饰用于在整个链接阶段保留类型信息。(请参阅修饰名)
参数应在堆栈上出现的顺序。
函数返回时调整堆栈的责任。 已调用的函数或正在调用的函数负责。
隐藏参数的传递(无论是否传递所有隐藏参数)。
extern string-literal { declaration-list }
extern string-literal declaration
通过允许使用现有代码,链接规范逐渐简化了 C 代码到 C++ 的移植。
Microsoft 专用
Microsoft C++ 当前支持的唯一链接规范为“C”和“C++”。
结束 Microsoft 专用
以下示例使用 C 链接声明函数 atoi 和 atol:
extern "C"
{
int atoi( char *string );
long atol( char *string );
}
对这些函数的调用是使用 C 链接执行的。 利用下面两个声明也可以实现相同的结果:
extern "C" int atoi( char *string );
extern "C" long atol( char *string );
Microsoft 专用
所有 Microsoft C 标准都包含用于检测 C++ 编译的文件使用条件编译指令。 当检测到 C++ 编译时,原型将包含在 extern "C" 指令中,如下所示:
// Sample.h
#if defined(__cplusplus)
extern "C"
{
#endif
// Function declarations
#if defined(__cplusplus)
}
#endif
结束 Microsoft 专用
您无需将标准包含文件中的函数声明为 extern "C"。
如果某个函数已重载,则不能有多个同名的函数具有链接说明符。(有关详细信息,请参阅函数重载。)
下表显示了各种链接规范的工作方式。
链接规范的效果
规范 |
效果 |
---|---|
针对对象 |
仅影响该对象的链接 |
针对函数 |
影响该函数和其中声明的所有函数或对象的链接 |
针对类 |
影响在该类中声明的所有非成员函数和对象的链接 |
如果函数有多个链接规范,则它们必须一致;将函数声明为同时具有 C 和 C++ 链接是错误的。 此外,如果一个函数的两个声明出现在一个程序中,并且它们一个有链接规范,另一个没有,则有链接规范的声明必须是第一个。 将为已具有链接规范的函数的所有冗余声明提供第一个声明中指定的链接。 例如:
extern "C" int CFunc1();
...
int CFunc1(); // Redeclaration is benign; C linkage is
// retained.
int CFunc2();
...
extern "C" int CFunc2(); // Error: not the first declaration of
// CFunc2; cannot contain linkage
// specifier.
在复合链接说明符 ({ }) 体中显式声明为 static 的函数和对象将视为静态函数或对象;将忽略此链接说明符。 其他函数和对象的行为方式就像它们是使用 extern 关键字声明的一样。(有关 extern 关键字的详细信息,请参阅使用 extern 指定连接。)