使用extern"C"在C文件中调用C++类函数

J D*_*oe. 2 c c++

我试图使用extern "C"能够在不同的C文件中调用C++类.我可以构建这个很好,直到我实际包含.h在C文件中我想从中调用C++类.

MyClass.cpp

MyClass::MyClass(){};
MyClass::~MyClass(){};

extern "C" void* MyClassInit(){
    return new MyClass();
}
Run Code Online (Sandbox Code Playgroud)

MyClass.h

extern "C" void* MyClassInit();
Run Code Online (Sandbox Code Playgroud)

好的 - 以上编译.但现在我想MyClassInit在另一个.c文件中使用.只要我

#include "MyClass.h" 在那个文件中,我得到了

error: expected identifier or '(' before string constantMyClass.h外部定义的地方.

我假设我错过了一些"if cplusplus"或其他extern或其他非常模糊的东西.

The*_*Vee 9

extern "C"在C中没有:C编译器不会理解这一点并且会阻塞它.您需要仅将此指令公开给C++编译器.这就是为什么经常在这样的标题中你找到这个(一个随机的例子,例如这里):

#ifdef __cplusplus
extern "C" {
#endif

... code ...

#ifdef __cplusplus
}
#endif
Run Code Online (Sandbox Code Playgroud)

C预处理器将删除extern "C",仅保留附带的代码,而对于C++编译器,同样的文件将如下所示

extern "C" {
... code ...
}
Run Code Online (Sandbox Code Playgroud)

更新:关于整个extern "C"构造的目的的几句话,以及为什么它只出现在C++中,正如Justin Randall在评论中所建议的那样.也许需要它的主要原因是它可以防止名称损坏.当存在相同名称的重载函数时,这很重要:错位名称是唯一的,因此可以区分这些名称.另一方面,C中没有过载,因此没有名称重整,也不需要extern块.

长话短说,一个典型的C++编译器倾向于重命名一个函数void f(),例如,类似于_Z1fv.但是C编译器会查找f并失败.extern "C"使前者使用后者所期望的相同符号名称.

可以在此处找到更精确的信息.