【问题标题】:using of extern "C" without function使用没有功能的外部“C”
【发布时间】:2012-10-22 09:15:20
【问题描述】:

我读了 Dale Rogerson 的书“Inside COM”。在第 5 章中,他写道(对不起,我翻译成英文):

extern "C" 用于 C 链接。如果一个函数被标记为extern "C", 编译器不会将函数的名称更改为其他名称,例如: ?CreateInstance@@YAPAUIUncnown@@XZ.

这对我来说很清楚。但作者进一步在其他地方使用extern "C",并没有解释它的原因:

#include <objbase.h>

extern "C" 
{
    // {32bb8320-b41b-11cf-a6bb-0080c7b2d682}
    extern const IID IID_IX = 
        {0x32bb8320, 0xb41b, 0x11cf,
        {0xa6, 0xbb, 0x0, 0x80, 0xc7, 0xb2, 0xd6, 0x82}} ;

    // {32bb8321-b41b-11cf-a6bb-0080c7b2d682}
    extern const IID IID_IY = 
        {0x32bb8321, 0xb41b, 0x11cf,
        {0xa6, 0xbb, 0x0, 0x80, 0xc7, 0xb2, 0xd6, 0x82}} ;

    // {32bb8322-b41b-11cf-a6bb-0080c7b2d682}
    extern const IID IID_IZ = 
        {0x32bb8322, 0xb41b, 0x11cf,
        {0xa6, 0xbb, 0x0, 0x80, 0xc7, 0xb2, 0xd6, 0x82}} ;

    // The extern is required to allocate memory for C++ constants.
}

这不是一个函数...为什么作者在这种情况下使用extern "C"

最好的问候, 安德烈

【问题讨论】:

    标签: c++ c com


    【解决方案1】:

    extern "C" 在这样的块上就像将 extern "C" 应用到块中的每个声明;它声明所有这些都使用 C 链接。

    非函数上的extern "C" 与函数上的extern "C" 做同样的事情;它使对象使用 C 语义进行命名,以及其他任何相关的内容。

    有关详细信息,您可能需要参考标准,第 7.5 条链接规范 [dcl.link](尽管它是使用难懂的英语形式编写的)。


    语言链接是为了使从不同语言访问声明的实体成为可能。这究竟意味着什么取决于特定的语言和 C++ 实现。传统上,对于 C,这意味着函数的符号和调用约定发生了变化。据我所知,在大多数实现中,非函数没有什么不同。只是语言规范并没有说除非您使用 extern "C",否则您可以期望从 C 访问这些实体。

    【讨论】:

    • 如果我从块中删除 'extern "C" ' 会有什么变化?
    • @Bush - 也许什么都没有。取决于编译器。一般来说,您希望能够从 C++ 和 C 中使用的东西应该标记为extern "C"
    【解决方案2】:

    对于您的问题,可能只是一个愚蠢的解决方法。我发现,在 cpp 文件中使用 c 函数时,理论上需要 extern。但是我发现在eclipse的氧气版本中,我们不必指定extern c,我们也可以在cpp文件中直接使用c函数和printf语句,就可以了。没有在旧版本的 eclipse 中尝试过。

    我的解决方案可能不是很有帮助,但您可以尝试一下。它对我有用。

    据我所记得的标准,所有函数声明默认都被认为是“extern”,所以没有必要明确指定。这不会使这个关键字无用,因为它也可以与变量一起使用(在这种情况下 - 它是解决链接问题的唯一解决方案)。但是有了这些功能 - 是的,它是可选的。

    更详细一点的答案是,它允许您使用在另一个源代码文件中编译的变量,但不为变量保留内存。因此,要使用 extern,您必须有一个源代码文件或一个库单元,其中包含顶层变量(而不是函数内)的内存空间。现在,您可以通过在其他源代码文件中定义同名的 extern 变量来引用该变量。

    一般来说,应该避免使用外部定义。它们很容易导致难以管理的代码和难以定位的错误。当然,也有其他解决方案不切实际的例子,但它们很少见。例如,stdin 和 stdout 是映射到 stdin.h 中 FILE* 类型的外部数组变量的宏;此数组的内存空间位于标准 C 库单元中。

    【讨论】:

      猜你喜欢
      • 2018-12-30
      • 1970-01-01
      • 2021-07-16
      • 1970-01-01
      • 2013-12-28
      • 1970-01-01
      • 1970-01-01
      • 2023-01-01
      • 1970-01-01
      相关资源
      最近更新 更多