为什么要使用'extern'C ++“'?

时间:2009-03-04 14:59:39

标签: c++ c

在此article中,关键字extern后面可以跟“C”或“C ++”。为什么要使用'extern'C ++“'?这是否实用?

11 个答案:

答案 0 :(得分:99)

语言允许:

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

如果foo.h包含需要C ++链接的内容怎么办?

    void f_plain(const char *);
    extern "C++" void f_fancy(const std::string &);

这就是你如何保持链接器的快乐。

答案 1 :(得分:32)

没有真正的理由使用extern "C++"。它只是明确了隐式默认的链接。如果你有一个类,其中一些成员有外部“C”链接,你可能希望明确说明其他成员是外部“C ++”。

请注意,C ++标准在语法上定义extern "anystring"。它只给出extern "C"extern "C++"的正式含义。如果他们愿意,编译器供应商可以自由定义extern "Pascal"甚至extern "COM+"

答案 2 :(得分:18)

我不确定你为什么需要这样做,但是根据Sun的this文章,你可以在extern“C”块中使用extern“C ++”来指定组中的某些函数“C”函数具有本机C ++链接。

extern "C" {
    void f();             // C linkage
    extern "C++" {
        void g();         // C++ linkage
        extern "C" void h(); // C linkage
        void g2();        // C++ linkage
    }
    extern "C++" void k();// C++ linkage
    void m();             // C linkage
}

答案 3 :(得分:6)

两个猜测:

  • 如果您在extern "C"块中,则可以通过指定嵌套extern "C++"来再次获得C ++语言链接。
  • 它保留C++链接,因为它是定义C ++的文档。谁能更好地定义C++语言链接而不是它本身。它还提供完整性。与signed/unsigned相同的交易。

阅读解释extern "LanguageName"的{​​{3}}(即GCC有extern "Java")。

答案 4 :(得分:3)

外部“C”被许多人回答。 extern“C ++”的用例是在C函数中调用C ++库函数时。相关的子用例是将C ++库与带有main函数的C源代码链接起来。请查看此wiki page了解详情:

答案 5 :(得分:2)

C和C ++使用不同的name mangling rules。本质上,extern“C”告诉C ++编译器将函数命名为C命名它。

答案 6 :(得分:1)

指定要使用的链接约定。大多数语言都知道如何与“C”风格函数链接。

在两种情况下你需要这个:

  • 用于该事项的C语言或其他语言程序调用用C ++编写的函数
  • 调用用C
  • 编写的函数的C ++程序

示例:

// declared in function.h
void f1(void);

您的C代码 - 实际上其他语言能够与C函数链接 - 将无法链接到它,因为对象表中的名称将使用C ++约定。

如果你写

extern "C" void f1(void);

现在链接有效,因为它使用C约定。

答案 7 :(得分:1)

我使用extern“C”的第一个原因是避免使用C ++的名称修改规则。如果您使用.Net语言并希望将PInvoke转换为特定的本机函数,这一点非常重要。唯一的方法是禁用名称修改。

答案 8 :(得分:0)

回答第二个问题,“它实用吗?”:

在像 <cmath> 这样的标准标头中,这是实用的,而且几乎是不可避免的。

想象一个只有头文件的库 X.h,它是用 C++ 和 C 的一个公共子集编写的,并且打算在两种语言中使用。为了 C++ 用户的利益,X.h 包含 <cmath>,而不是 <math.h>。但是,这对 C 用户不起作用,如果 <cmath> 的作者没有将所有内容都夹在 extern "C++" { ... } 中。

答案 9 :(得分:-1)

简短的回答是你可以使用extern C告诉编译器不要使用名称修改。这意味着您可以将同一项目中的C和C ++代码链接在一起。

答案 10 :(得分:-2)

extern“C”用于表示C ++函数应该具有C链接。这意味着依赖于实现,但通常会关闭C ++名称修改(以及重载和严格类型检查)。当你想要从C代码调用C ++函数时使用它:

extern "C" void Foo();   // can be called easily from C

至于extern“C ++”,我从未在实际代码中看到它,尽管C ++标准允许它。我想这是一个无操作。