外部"C"是否应包含C++函数的声明或定义?

Tim*_*Tim 13 c c++

我在一个cpp文件中看到,它external "C" {...}包含了几个函数的定义.

https://isocpp.org/wiki/faq/mixing-c-and-cpp,我想extern "C"在cpp文件中使用的目的是使附带的C++函数可用于C程序.

链接中的示例显示仅extern "C"包含C++函数的声明,而不是它们的定义

只需声明C++函数extern"C"(在您的C++代码中)并调用它(从您的C或C++代码).例如:

    // C++ code:
    extern "C" void f(int);
    void f(int i)
    {
        // ...
    }
Run Code Online (Sandbox Code Playgroud)

我在开头提到的cpp文件看起来像:

    // C++ code:
    extern "C" {

    void f(int i)
    {
        // ...
    }

    void g(int i)
    {
        // ...
    }

    }
Run Code Online (Sandbox Code Playgroud)

是否应该extern "C"包含C++函数的声明或定义?如果是这样,为什么?

πάν*_*ῥεῖ 15

它应该将声明括在头文件中,并且只要使用c ++编译器编译转换单元就应该包含定义,并且只要在那里看不到声明.
在c ++代码中同时执行这两项操作永远不会错.

如果c编译器用于编译函数定义,则没有必要(或者我应该更好地说语法错误,请参阅下面的注释).

extern "C" {}范围控制普通c符号链接用于内部的所有内容.否则将应用c ++名称修改.


注意:

由于extern "C" {}这不是有效的c语法,为了使其与c编译器一起使用,您需要在以下内容中使用它#ifdef:

MyHeader.h:

 #ifdef __cplusplus
 extern "C" {
 #endif

 // ... c style function name declarations
 void foo(int i);

 #ifdef __cplusplus
 } // extern "C"
 #endif
Run Code Online (Sandbox Code Playgroud)

extern "C" {}范围的使用实际上是双重的:


将C++代码导出到C

如果使用c编译器编译上述内容,则它将作为普通的c函数声明出现.如果使用c ++编译器编译,则应用extern关键字并且将禁止c ++名称修改.

关于定义,函数可以使用其定义中的任何c ++特性:

 extern "C" {
     void foo(int x) {
         std::vector v(x);
         // ... blah, more c++ stuff
     }
 }
Run Code Online (Sandbox Code Playgroud)

请注意,此处未包含声明.这可以用作一种技术,当您想要覆盖从库中暴露的弱连接函数时,这种技术特别有用.

在包括的情况下MyHeader.h,该extern "C" {}范围可被省略.


从C++导入C代码

如果在c ++编译器中看到上述声明,则再次禁止c ++名称修改,并且foo()链接器将使用普通c函数符号名称解析对任何调用引用:

  #include "MyHeader.h"
  class MyClass {
  public:
       void bar(int y) {
           // Use foo() as plain c function:
           foo(y);
       }
  };
Run Code Online (Sandbox Code Playgroud)

foo()功能实现是从使用C编译器创建的对象文件(或归档)提供.


T.C*_*.C. 7

[dcl.link]/5:

除了具有C++链接的函数之外,没有链接规范的函数声明不应位于该函数的第一个链接规范之前.在看到明确的链接规范之后,可以在没有链接规范的情况下声明函数; 前面声明中明确指定的链接不受此类函数声明的影响.

就函数的语言链接而言,两个版本都很好.重要的是,函数的第一个声明必须具有extern "C"它.

  • 因此,这实际上意味着,如果之前在 `extern "C" {}` 范围内声明了一个函数,则定义将引用此声明,无论它是编译为 c++ 还是 c 代码? (2认同)