繁体   English   中英

何时使用extern“C”?

[英]When to use extern “C”?

我知道如何使用extern "C"但是你必须使用它的条件是什么?

extern "C"告诉C ++编译器不要对大括号内的代码执行任何名称修改。 这允许您从C ++中调用C函数。

例如:

#include <string.h>

int main()
{
    char s[] = "Hello";
    char d[6];

    strcpy_s(d, s);
}

虽然这在VC ++上编译得很好。 但有时这写成:

extern "C" {   
#include <string.h>  
}

我没有看到这一点。 你能给出一个真实的例子,其中extern "C"是必要的吗?

您可以使用extern "C"来防止头文件中的名称损坏以及已编译但未编译的库或对象的 C ++目标文件

例如,假设您有一个使用C编译器编译的widget库,以便其已发布的接口不受损坏。

如果将头文件原样包含在代码中,它将假定名称破坏,并且那些受损的版本是您将告诉链接器要查找的内容。

但是,既然你要求function@intarray_float_charptr这样的东西,而且widget库只有已发布的function ,你就会遇到问题。

但是,如果您将其包含在:

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

你的编译器会知道应该尝试使用非破坏版本的function

这就是为什么在C语言的头文件意味着包含在C _或C ++程序中,你会看到如下内容:

#ifdef __cplusplus
    extern "C" {
#endif

// Everything here works for both C and C++ compilers.

#ifdef __cplusplus
    }
#endif

如果使用C编译器来包含它, #ifdef行将导致extern "C"内容消失。 对于C ++编译器(其中定义了__cplusplus ),一切都将是非破坏的。

从库中导出函数时, extern "C"一个非常常见的用法。 如果不禁用C ++名称修改,则可能会使库的客户端很难命名您的函数。 同样,当您向另一个方向前进时,导入已使用C链接导出的函数时。

这是一个具体的例子,其中的东西破碎,需要extern "C"来修复。

module.h

int f(int arg);

module.c

int f(int arg) {
  return arg + 1;
}

main.cpp

#include "module.h"

int main() {
  f(42);
}

由于我混合使用C和C ++,因此不会链接(在两个目标文件中,只有一个会在其C ++受损名称下知道f )。

也许最简单的解决方法是使头文件兼容C和C ++:

module.h

#ifdef __cplusplus
  extern "C" {
#endif

int f(int arg);

#ifdef __cplusplus
  }
#endif

当你与被写在C库链接extern告诉编译器不装饰的名称,以便链接可以找到的功能。 在C ++中,函数名称等具有链接器的信息,例如名称中包含的参数类型和大小。

如果要生成二进制库A,它公开要从二进制B调用的函数。

想象一下A是A.dll,B是B.exe,你在Windows系统上。

C ++没有描述二进制布局,因此B知道如何调用A.通常,使用相同的编译器生成A和B可以解决此问题。如果需要更通用的解决方案,请使用extern关键字。 这以C方式公开该功能。 C确实描述了二进制格式,以便来自不同编译器的不同二进制文件可以相互通信。

请参阅: http//en.wikipedia.org/wiki/Application_binary_interface http://en.wikipedia.org/wiki/Name_mangling#Name_mangling_in_C.2B.2B

如果在C ++代码中, #include外部库的头文件(用C编码),如果那里的函数没有声明为extern "C"那么它们就不会工作(你会在链接时得到未定义的引用)。

但是现在,编写C库并为您提供头文件的人倾向于知道这一点,并且经常将extern "C"放在他们的头文件中(适当地用#ifdef __cplusplus保护)

也许更好的理解方法是使用(假设您有一个Linux系统) nm实用程序来向您显示库或可执行文件中使用的(未编码的)名称。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM