链接指示:extern "C"

某日,在我学习C++的异常处理时,碰巧打开了 exception 头文件,在浏览这个头文件的时候发现了一个从未看过的语句:

extern "C++" {...}

当是很是好奇,赶紧翻阅了C++圣经 《C++ Primer》,圣经不愧是圣经,果然是海纳百川啊!
原来这玩意儿是 链接指示

C++程序有时需要调用其他语言编写的函数,最常见的就是调用C语言编写的函数。像所有其他名字一样,其他语言中的函数名字也必须在C++中进行声明,并且该声明必须指定返回类型和形参列表。对于其他语言编写的函数来说,编译器检查其调用的方式与处理普通的C++函数的方式相同,但是生成的代码有所区别。C++使用链接指示(linkage directive)指出任意非C++函数所用的语言。

以上的引用就来自C++圣经,解释的也很通透,反正我当时看完一遍就明白是咋回事了(但是有个小小的好奇就是为啥我发现这个问题是在编写C++程序时发现的?异常处理中的exception头文件不是C++的头文件吗?预知后事如何请继续阅读)。Shortly,这个 extern “C”的意思就是在C++的程序中使用了C语言编写的函数。

那怎么使用这个链接指示呢?

  1. 声明一个非C++的函数

    extern “XXX”

“XXX”这个字符串字面值常量指出了编写函数所用的语言,如 extern “Ada”, extern “FORTRAN”, extern “C”(接下来我们主要以这个举例)。
注意:当把其他语言和C++放在一块使用时,要求我们必须能访问其他语言的编译器,并且这个编译器与当前的的C++编译器是兼容的。
链接有两种:单个的或复合的。很简单,单个的就是单独声明一个非C++函数,复合的就是声明一组非C++函数。

extern "C" size_t strlen(const char*);

extern "C"{
    int strcmp(const char*, const char*);
    char *strcat(char*, const char*);
}
  1. 链接指示与头文件

类似链接指示的复合形式,多重声明的形式可以应用到整个头文件。例如,C++的头文件cstring可能是这样的:

extern "C"{
    #include <string.h>
}
  1. 指向extern “C”的函数指针
    编写函数所用的语言是函数类型的一部分!
    所以,对于使用链接指示定义的函数,它的每个声明都必须使用相同的链接指示。而且,指向其他语言编写的函数的指针必须与函数本身使用相同的链接指示。
    也就是说,指向C函数的函数指针与指向C++函数的指针是不一样的。
extern "C" void (*pf) (int);

当我们使用pf调用函数时,编译器认定当前调用的是一个C函数。
而且,链接指示对整个生命都是有效的。它不仅对函数有效,而且对最为返回类型或者形参类型的函数指针也有效:

extern "C" void f1(void (*)(int));

当调用f1时,必须传给它一个C函数的名字或者指向C函数的指针。
当我们想向C++函数传入一个C函数的指针时,则必须使用类别名:

extern "C" typedef void FC(int);
//f2是一个C++函数,该函数的形参是指向C函数的指针
void f2(FC *);
  1. 导出C++函数到其他语言
    通过使用链接指示对函数进行定义,可以另一个C++函数在其他语言编写的程序中可用:
//calc函数可以被C程序调用
extern "C" double calc(double dplarm) {/*...函数定义...*/};

所以,困扰我半天的 extern "C++" {...} 就是这个意思?

注意:
可被多种语言共享的函数的返回类型和形参类型收到很多限制。重点内容

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
extern "C"的作用是用于实现C和C++之间的相互调用问题。C和C++对于函数名的处理方式是不一样的,所以当我们希望调用其他用C编写的函数时,需要告诉编译器使用不同的要求。通过在C++代码中使用extern "C"来声明函数,可以使编译器按照C的规则来处理函数名和参数排列的顺序,从而实现C和C++之间的兼容调用。 需要注意的是,extern "C"不能在函数内部使用,而是用于函数的声明。如果一个函数有多个声明,可以都加上extern "C",或者只在第一次声明中出现,后面的声明会接受第一个链接指示符的规则。 所以当我们需要在C++代码中调用C函数时,可以使用extern "C"来实现对C函数的调用。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* *3* [【004 关键字】extern “C“的作用是什么?](https://blog.csdn.net/qq_41709234/article/details/123082378)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] - *2* [extern关键字作用.docx](https://download.csdn.net/download/Stephen___Qin/87567249)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值