C++ 什么时候是;外部C";在c+中是必需的+;在窗户里?

C++ 什么时候是;外部C";在c+中是必需的+;在窗户里?,c++,c,windows,C++,C,Windows,正如我们所知,我们可以在c++中直接使用c函数,当extern“c”必要时?当c++函数必须由c代码而不是c++代码调用时,这是必要的 基本上,当您希望C++库向后兼容时 如果函数是在.c文件中实现的,.cpp文件将需要外部“c”引用,否则它们将引用一个损坏的c++风格函数名,链接将失败 P>从DLL导出函数也是方便的,因此它们以非被损坏的名称导出。< P>因为C++和C++编译器生成的函数签名不同,这就建立了C函数的C约定,即使使用C++时也不成立。使用不同的参数多次定义相同的函数或方法。要

正如我们所知,我们可以在c++中直接使用c函数,当
extern“c”
必要时?

c++
函数必须由
c
代码而不是
c++
代码调用时,这是必要的


基本上,当您希望
C++
库向后兼容时

如果函数是在.c文件中实现的,.cpp文件将需要外部“c”引用,否则它们将引用一个损坏的c++风格函数名,链接将失败


<> P>从DLL导出函数也是方便的,因此它们以非被损坏的名称导出。

< P>因为C++和C++编译器生成的函数签名不同,这就建立了C函数的C约定,即使使用C++时也不成立。使用不同的参数多次定义相同的函数或方法。要做到这一点,编译器必须为每一个添加部分符号。。。例如,编译器将在以下声明中更改函数名foo 从

不幸的是,C不支持这一点。编译后,所有函数名保持不变。因此,要调用C++中的C++函数,必须知道修改后的确切名称,并且我认为它是困难的,并且不同于编译器。 围绕此工作并能够调用C++函数,并停止编译器更改名称,则必须使用这个关键字,如

extern "C" { 
void foo(int f,char c);
}

就这样

外部“C”有两种截然不同的用法。一个是定义C++中的函数,你应该能够从C++调用,也就是说,你在C++中编写代码,但是它需要与C代码进行接口。在这种情况下,将函数定义为
extern“C”

当您这样做时,这些函数的接口必须遵循与C中几乎相同的规则(例如,您不能重载函数或对任何参数使用默认值)

另一个(相当常见的)情况是,你有C编写的代码,你想能够从C++调用。在这种情况下,函数定义与以前完全相同,但函数需要声明/原型为

extern“C”
。在一个典型的例子中,你想使用一个可以在 >的单个标题,它的结构看起来类似于:

// myheader.h
#ifndef MY_HEADER_H_INCLUDED_
#define MY_HEADER_H_INCLUDED_

#ifdef __cplusplus
extern "C" {
#endif

    int func1(void);
    void func2(int);

#ifdef __cplusplus
}
#endif

#endif
< >,C++编译器将看到函数声明(和<代码> TyPulfF</代码> s等),由一个<代码>外部“C”< /C>块,而C编译器将看到原型,而不是被它不认识的东西包围。

第一种情况(C++中调用C++函数),通常会以大致相同的方式构造报头,如果需要的话,也可以从C++调用这些函数(但是在接口上,仍然会丢失C++类函数重载的所有额外特性)。啊!如果项目是

C
,不要将
C++
添加到项目中:将其转换为
C++
,如果需要,将
C
添加到
C++
项目中。或者(更好的做法是)将其保存在
C
中,并避免使用
C++
。这个答案是正确的,但不完整,就像@Graham Perks的答案一样,也是正确的,但不完整。整个答案将是两者的总和。@pmg:即使您的库是用C++开发的,您也可能无法拥有C项目或更改他们想要的接口。@pmg:考虑外部库和回调。@pmg:为什么不完全避免使用C?这个答案是正确的,但不完整,就像@Randolpho的答案一样,这也是正确的,但不完整。整个答案是两个的总和。1个用来解释原因,但是这也发生在相反的方向:如果你在C中有一个函数在一个库中,并且你的头没有“<代码>外”“C”<代码>限定符,C++编译器会损坏符号。然后,在链接阶段,它将尝试查找损坏的符号,但无法找到,因为c编译器在编译c代码时没有损坏名称。
extern "C" { 
void foo(int f,char c);
}
extern "C" {
    int c_callable_func1() {}
    int c_callable_func2() {}
}
// myheader.h
#ifndef MY_HEADER_H_INCLUDED_
#define MY_HEADER_H_INCLUDED_

#ifdef __cplusplus
extern "C" {
#endif

    int func1(void);
    void func2(int);

#ifdef __cplusplus
}
#endif

#endif