使用无功能的外部"C"

using of extern "C" without function

本文关键字:外部 功能      更新时间:2023-10-16

我读了戴尔·罗杰森(Dale Rogerson)的书《 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"

最好的问候,Andrey

extern" c",就像将extern" c"应用于块中的每个声明;它声明所有这些都使用C链接。

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

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


语言链接是可以从其他语言访问声明的实体。这到底意味着特定语言和C 实现。传统上,用c这意味着符号和呼叫功能的惯例已更改。据我所记得的,在大多数实现中,非功能没有什么不同。只是语言规范并没有说您可以期望访问从C起作用的这些实体,除非您使用extern" c"。

可能只是您问题的愚蠢解决方法。我发现,在CPP文件中使用C函数时,理论上需要外部。但是我发现,在Eclipse氧气版本中,我们不必指定外部C,我们也可以在CPP文件中直接使用C函数和printf语句,而且效果很好。在旧版本的日食中尝试了。

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

据我记得的标准,默认情况下,所有功能声明都被视为"外部",因此无需明确指定它。这并不能使此关键字无用,因为它也可以与变量一起使用(并且是这种情况 - 它是解决链接问题的唯一解决方案)。但是有功能 - 是的,它是可选的。

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

通常,应避免使用外部定义。它们很容易导致无法控制的代码和错误。当然,有一些例子是其他解决方案是不切实际的,但很少见。例如,stdin和stdout是宏观映射到stdin.h中类型文件*的外部数组变量的宏;此数组的存储空间位于标准的C图单元中。