链接指示 重学extern关键字

tech2026-08-23  1

C++程序有时候需要调用其他语言编写的函数,比如调用C语言编写的函数。如同调用C++函数一样,要调用其他语言编写的函数,也必须进行声明并确定形参列表和函数返回值。 对于其他语言编写的函数来说,编译器检查和调用的处理方式与普通C++函数一致,但是生成的代码有所区别。 C++使用链接指示linkage directive 指出任意非C++函数所用的语言。 注:要想在c++代码中使用其他语言编写的代码,要求必须有权访问该语言的编译器,并且这个编译器与当前C++的编译器是兼容的。

项目包含一个test01.h头文件和包含主函数的cpp文件。欢迎指出错误。

/* test01.h */ #pragma once; #include <iostream> /* extern "C++"{//这里不能写成extern "C++"{fun2(void),fun2(int);}的形式,因为本身就是c++的编译方式 void fun2() { std::cout << "这是C++编写的函数fun2(void)" << std::endl; printf_s("这是C++编写的函数fun2(void)"); } //这里fun(int a)如果不加extern "C++"的话,会报错。 //在这里发生了函数重载,C++支持函数重载,C不支持。 void fun2(int a) { std::cout << "这是C++编写的函数fun2(int a)" << std::endl; printf_s("这是C++编写的函数fun2(int a)"); } } */ void fun2(int a) { std::cout << "这是C++编写的函数fun2(void)" << std::endl; printf_s("这是C++编写的函数fun2(void)"); } //这里fun(int a)如果不加extern "C++"的话,会报错。 //在这里发生了函数重载,C++支持函数重载,C不支持。 //void fun2(int a) { // std::cout << "这是C++编写的函数fun2(int a)" << std::endl; // printf_s("这是C++编写的函数fun2(int a)"); //} /*主函数cpp*/ #include <iostream> #include <vector> #include <string> //#include "test01.h" using namespace std; #ifdef __cplusplus extern "C" #endif // __cplusplus void fun5() { cout << "注意看预编译的时候去掉预编译宏的效果" << endl; } /* 如果是按照c++的方式编译,则去掉预编译宏后 的效果,是告诉编译器fun5()函数按照C的方式生成代码 extern "C" void fun5() { cout << "注意看预编译的时候去掉预编译宏的效果" << endl; } */ /* C++程序有时候需要调用其他语言编写的函数,比如调用C语言编写的函数。如同调用C++函数一样,要调用其他语言编写的函数,也必须进行声明并确定形参列表和函数返回值。 对于其他语言编写的函数来说,编译器检查和调用的处理方式与普通C++函数一致,但是生成的代码有所区别。 C++使用链接指示linkage directive 指出任意非C++函数所用的语言。 注:要想在c++代码中使用其他语言编写的代码,要求必须有权访问该语言的编译器,并且这个编译器与当前C++的编译器是兼容的。 */ //链接指示不能出现在类内或者函数体内。意思是在类内核函数体内不能使用extern extern "C" {//编译器应该支持C语言的链接指示 也可以是extern "FORTRAN" /* gcd(a,b)==1说明a,b互质 辗转相除法,又称欧几里得算法,时间复杂度log2 N */ size_t gcd(int n, int m) //这是一个求两个数最大公约数的函数,使用辗转相除法 { if (m == n)return n; if (n > m) { int temp = n; n = m; m = temp; }//保证m是大值 while (n>0) { int ret = m % n; m = n; n = ret; } return m; }; //此部分会生成c的代码,而不是cpp的代码 } //这里不能写成extern "C++" 会报错,因为本身就是C++的编译方式 extern "C" {//告诉编译器,头文件test01.h按照C语言的方式进行编译 #include "test01.h" /* 使用extern "C"告诉编译器头文件按照C语言的方式进行编译,如果在头文件中出现了函数重载, 编译器报:不允许重载函数的C链接 */ } //int fun1() { // extern "C" void f() {};//提示不允许使用链接规范 //} void fun4(int a) { cout << "这是C++方式编译的fun4(int)函数" << endl; } //指向extern "C"的函数指针 extern "C" void(*pf)(int)=fun2;//pf指向一个C函数,该函数接收int,返回void extern "C" void(*pf2)(int) = fun4;//没有报错。根据C++ Primer说C的函数指针只能接收C的函数地址,但是这里pf2接收了C++的fun4函数的地址。 int main() { fun2(0); //pf = &fun2; (*pf)(0); (*pf2)(0); pf = pf2;//没有报错,与Primer书上描述的不一致。 (*pf)(0); return 0; }
最新回复(0)