C ++中extern“C”的效果是什么?

extern "C"放到C ++代码中究竟做了什么?

例如:

extern "C" {
   void foo();
}

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

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

大家知道,你可以明确地为每个单独的声明/定义指定“C”链接,或者使用一个块将一系列声明/定义分组,以具有特定的链接:

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

如果您关心技术问题,那么它们将在C ++ 03标准的第7.5节中列出,这里是一个简短的摘要(重点在于extern“C”):

  • extern“C”是一个连接规范
  • 每个编译器都需要提供“C”链接
  • 链接规范只能出现在命名空间范围内
  • 所有函数类型,函数名称和变量名称都具有语言链接请参见Richard的注释:只有具有外部链接的函数名称和变量名称具有语言链接
  • 具有不同语言链接的两种功能类型是不同的类型,即使其他方面相同
  • 联动规格嵌套,内在联系规定最终联动
  • 对于班级成员,外部“C”被忽略
  • 最多一个具有特定名称的函数可以具有“C”连接(不管名称空间)
  • extern“C”强制一个函数具有外部链接(不能使其静态)参见Richard的评论:'extern'中的'static'C''是有效的; 如此宣布的实体具有内部联系,因此没有语言联系
  • 从C ++到其他语言中定义的对象与其他语言中定义在C ++中的对象之间的链接是实现定义的和语言相关的。 只有两种语言实现的对象布局策略足够相似,才能实现这种连接

  • 只是想添加一些信息,因为我还没有看到它发布。

    你会经常在C头文件中看到代码,如下所示:

    #ifdef __cplusplus
    extern "C" {
    #endif
    
    // all of your legacy C code here
    
    #ifdef __cplusplus
    }
    #endif
    

    这实现的目的是它允许你在你的C ++代码中使用这个C头文件,因为宏“__cplusplus”将被定义。 但是,您仍然可以将其与遗留的C代码一起使用,因为它没有定义宏,所以它不会看到独特的C ++构造。

    虽然,我也看到了C ++代码,例如:

    extern "C" {
    #include "legacy_C_header.h"
    }
    

    我想象的是完成了很多相同的事情。

    不知道哪种方式更好,但我都看到了。


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

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

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

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

    这在使用dlsym()dlopen()来调用这些函数时非常方便。

    链接地址: http://www.djcxy.com/p/1055.html

    上一篇: What is the effect of extern "C" in C++?

    下一篇: Meaning of "const" last in a C++ method declaration?