使用extern“C”没有功能

时间:2012-11-01 18:02:22

标签: c++ c com

我读过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"

最诚挚的问候, 安德烈

2 个答案:

答案 0 :(得分:4)

像这样的块上的extern“C”就像将extern“C”应用于块中的每个声明一样;它声明所有这些都使用C链接。

非函数上的extern“C”与函数上的extern“C”表示相同;它使对象使用C语义进行命名,以及其他相关内容。

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


语言链接是为了能够从不同的语言访问声明的实体。这究竟意味着什么取决于特定的语言和C ++实现。传统上使用C表示函数的符号和调用约定已更改。据我所知,在大多数实现中,对于非功能没有任何不同。只是语言规范没有说你可以期望从C中访问这些实体,除非你使用extern“C”。

答案 1 :(得分:0)

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

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

据我记得标准,所有函数声明都被视为&#34; extern&#34;默认情况下,因此无需明确指定它。这并不能使这个关键字变得无用,因为它也可以用于变量(在这种情况下 - 它是解决链接问题的唯一解决方案)。但是有了这些功能 - 是的,它是可选的。

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

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