java extern的作用_C ++中extern“ C”的作用是什么?

将extern "C"放入C ++代码到底能做什么?

例如:

extern "C" {

void foo();

}

#1楼

extern“ C”旨在由C ++编译器识别,并通知编译器所注明的功能已(或将要)以C样式进行编译。 这样,在链接时,它会链接到C中正确版本的函数。

#2楼

它通知C ++编译器在链接时以C样式查找这些函数的名称,因为在链接阶段,用C和C ++编译的函数的名称不同。

#3楼

它以一种可从C调用该函数的方式更改函数的链接。实际上,这意味着函数名称不会被修饰 。

#4楼

extern“ C”使C ++中的函数名称具有'C'链接(编译器不会更改名称),以便客户端C代码可以使用'C'兼容的头文件链接到(即使用)您的函数,该头文件仅包含函数的声明。 函数定义以二进制格式(由C ++编译器编译)包含,客户端“ C”链接器随后将使用“ C”名称链接至该二进制文件。

由于C ++具有重载的函数名,而C没有重载,因此C ++编译器不能仅使用函数名作为要链接的唯一ID,因此它通过添加有关自变量的信息来破坏名称。 AC编译器不需要处理名称,因为您不能在C中重载函数名称。当您声明函数在C ++中具有外部“ C”链接时,C ++编译器不会将参数/参数类型信息添加到用于连锁。

众所周知,您可以显式地为每个单独的声明/定义指定“ C”链接,也可以使用一个块对一系列声明/定义进行分组以具有一定的链接:

extern "C" void foo(int);

extern "C"

{

void g(char);

int i;

}

如果您关心技术方面的问题,它们会在C ++ 03标准的7.5节中列出,此处是一个简短的摘要(着重于外部“ C”):

extern“ C”是一个链接规范

每个编译器都需要提供“ C”链接

链接规范应仅在命名空间范围内发生

所有函数类型,函数名称和变量名称都具有语言链接。 请参阅Richard的注释:只有具有外部链接的函数名称和变量名称才具有语言链接。

即使语言相同,具有不同语言链接的两个函数类型也都是不同类型

链接规格嵌套,内部决定最终的链接

类成员忽略外部“ C”

最多一个具有特定名称的函数可以具有“ C”链接(无论名称空间如何)

extern“ C”强制函数具有外部链接(不能使其静态) 请参见Richard的评论: 'extern“ C”'内部的'static'有效; 如此声明的实体具有内部链接,因此没有语言链接

从C ++到其他语言定义的对象以及从其他语言到C ++定义的对象的链接是实现定义的和语言相关的。 只有两种语言实现的对象布局策略足够相似时,才能实现这种链接

#5楼

在每个C ++程序中,所有非静态函数在二进制文件中均以符号表示。 这些符号是特殊的文本字符串,可唯一标识程序中的功能。

在C语言中,符号名称与函数名称相同。 这是可能的,因为在C中,没有两个非静态函数可以具有相同的名称。

由于C ++允许重载,并且具有C所不允许的许多功能(例如类,成员函数,异常规范),因此无法简单地将函数名用作符号名。 为了解决这个问题,C ++使用了所谓的名称修饰,将函数名称和所有必要的信息(例如参数的数量和大小)转换为一些仅由编译器和链接器处理的怪异字符串。

因此,如果将函数指定为extern C,则编译器不会对其进行名称修饰,并且可以使用其符号名作为函数名称直接对其进行访问。

这在使用dlsym()和dlopen()调用此类函数时非常方便。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值