C 中 extern "C" 的作用是什么?

新手上路,请多包涵

extern "C" 放入 C++ 代码到底有什么作用?

例如:

 extern "C" {
   void foo();
}

原文由 Litherum 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 581
2 个回答

extern "C" 使 C++ 中的函数名具有 C 链接(编译器不会破坏名称),以便客户端 C 代码可以使用仅包含声明的 C 兼容头文件链接到(使用)您的函数你的功能。您的函数定义包含在二进制格式(由您的 C++ 编译器编译)中,然后客户端 C 链接器将使用 C 名称链接到该格式。

由于 C++ 有函数名重载,而 C 没有,C++ 编译器不能只使用函数名作为链接的唯一 id,因此它通过添加有关参数的信息来破坏名称。 AC 编译器不需要修改名称,因为您不能在 C 中重载函数名称。当您声明一个函数在 C++ 中具有 extern "C" 链接时,C++ 编译器不会将参数/参数类型信息添加到用于链接的名称。

如您所知,您可以明确指定 extern "C" 链接到每个单独的声明/定义,或使用块将声明/定义序列分组以具有一定的链接:

 extern "C" void foo(int);
extern "C"
{
   void g(char);
   int i;
}

如果您关心技术细节,它们在 C++03 标准的第 7.5 节中列出,这里是一个简短的摘要(重点是 extern "C" ):

  • extern "C" 是一个链接规范
  • 每个编译器都 需要 提供“C”链接
  • 链接规范应仅出现在命名空间范围内
  • 所有函数类型、函数名和变量名都有语言链接 参见 Richard 的评论: 只有具有外部链接的函数名和变量名才有语言链接
  • 具有不同语言链接的两个函数类型是不同的类型,即使其他方面相同
  • 联动规格嵌套,内一决定最终联动
  • extern "C" 被类成员忽略
  • 至多一个具有特定名称的函数可以具有“C”链接(无论命名空间如何)
  • extern "C" 强制函数具有外部链接(不能使其静态) 参见 Richard 的评论: static inside extern "C" 是有效的;如此声明的实体具有内部链接,因此没有语言链接
  • 从 C++ 到用其他语言定义的对象以及从其他语言到用 C++ 定义的对象的链接是实现定义和语言相关的。只有在两种语言实现的对象布局策略足够相似的情况下,才能实现这样的联动

原文由 Faisal Vali 发布,翻译遵循 CC BY-SA 4.0 许可协议

C编译器编译的函数void f()和C++编译器编译的同名函数void f()不是同一个函数。如果您在 C 中编写了该函数,然后您尝试从 C++ 调用它,那么链接器将查找 C++ 函数但找不到 C 函数。

extern “C” 告诉 C++ 编译器你有一个由 C 编译器编译的函数。一旦你告诉它它是由 C 编译器编译的,C++ 编译器就会知道如何正确调用它。

它还允许 C++ 编译器以 C 编译器可以调用它的方式编译 C++ 函数。该函数将正式成为 C 函数,但由于它是由 C++ 编译器编译的,因此它可以使用所有 C++ 功能并具有所有 C++ 关键字。

原文由 gnasher729 发布,翻译遵循 CC BY-SA 4.0 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题