### 链接指示符 extern “C”

用户在阅读或修改他人的程序时，有时会遇到链接指示符 extern “C”（尤其是调用动态链接库时）。该指示符的作用是表示函数是使用其他语言写的。由于不同厂家、不同语言的编译器对函数的默认调用约定是不同的，因此导致不同语言对函数的参数处理顺序是不相同的。为了能够在 C++语言中调用其他语言编写的函数（通常以动态链接库的形式存在），需要使用链接指示符。以调用 C 语言的函数为例，C++程序中需要使用 extern ”C”链接指示符，注意，不要写成“extern ”c””，“C”必须大写。

extern ”C”链接指示符可以有 3 个方式标识函数。第一种方式是只标识一个函数。例如：

extern "C" bool Validate(float x )

第 2 种方式是使用复合语句标识一组函数。例如：

extern "C"

{

bool Validate(float x );

void OutputInfo(const char* pchData);

}

第 3 种方式是通过引用头文件来标识头文件中的所有函数。例如：

extern "C"

{

#include "inlinedemo.h"

}

在开发程序时，如果希望 C++语言编写的函数能够被 C 语言使用，也需要使用链接指示符 extern ”C”来标识函数。C++语言支持函数重载，程序编译后对函数名进行了命名改编，即代码中的函数名是“Validate”，但编译后程序中的函数名很可能不是“Validate”了。对于同一厂家的同一种编译器，相互调用是没有问题的（编译器知道如何解析函数名），但是不同厂家或不同语言的编译器调用函数就会出现问题。如下是动态链接库中的函数定义。

_declspec(dllexport)

bool Validate(int x) //定义一个导出函数

{

cout << "整型参数函数\n";

return (x > 0) ? true : false;

}

当代码编译为动态链接库之后，使用 depens 工具查看动态库链接库中的函数，发现名称发生了改变。图 1 描述的是 C++语言编写的动态链接库，代码中的函数名为“Validate”，但编译为动态链接库之后，函数名发生了改变。

图 1 命名改编

如果使用链接指示符 extern ”C”，情况就不同了，修改动态链接库中的 Validate 函数。

extern "C" //链接指示符

_declspec(dllexport) //标识导出函数

bool Validate(int x) //定义一个导出函数

{

cout << "整型参数函数\n";

return (x > 0) ? true : false;

}

重新编译动态链接库，使用 depens 工具查看动态库链接库中的函数，发现动态库链接库中的函数名称没有发生改变，即 Validate。如图 2 所示。

图 2 命名改编 2