简体   繁体   English

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

[英]Calling C++ class functions in C file using extern “C”

I am trying to use extern "C" to be able to call a C++ class within a different C file. 我试图使用extern "C"来能够在不同的C文件中调用C ++类。 I can build this fine until I actually include the .h in the C file I want to call the C++ class from. 我可以构建这个很好,直到我实际上将.h包含在我要调用C ++类的C文件中。

MyClass.cpp MyClass.cpp

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

extern "C" void* MyClassInit(){
    return new MyClass();
}

MyClass.h MyClass.h

extern "C" void* MyClassInit();

OK - the above compiles. 好的 - 以上编译。 But now I want to use MyClassInit in another .c file. 但现在我想在另一个.c文件中使用MyClassInit As soon as I 只要我

#include "MyClass.h" in that file I get #include "MyClass.h"我得到的那个文件中的#include "MyClass.h"

error: expected identifier or '(' before string constant in MyClass.h where the externs are defined. error: expected identifier or '(' before string constantMyClass.h中的error: expected identifier or '(' before string constant ,其中定义了externs。

I assume I am missing some "if cplusplus" or another extern or something else very obscure. 我假设我错过了一些“if cplusplus”或其他extern或其他非常模糊的东西。

There's no extern "C" in C: a C compiler won't understand this and will choke on it. extern "C"没有extern "C" :C编译器不会理解它并且会阻塞它。 You need to expose this directive to the C++ compiler only. 您需要仅将此指令公开给C ++编译器。 This is why often in such headers you find this instead (a random example eg here ): 这就是为什么经常在这样的标题中你找到这个(一个随机的例子,例如这里 ):

#ifdef __cplusplus
extern "C" {
#endif

... code ...

#ifdef __cplusplus
}
#endif

The C preprocessor will remove the extern "C" , keeping the enclosed code only, while for the C++ compiler, the same file will look like C预处理器将删除extern "C" ,仅保留附带的代码,而对于C ++编译器,相同的文件将看起来像

extern "C" {
... code ...
}

Update: A few words on the purpose of the whole extern "C" construct, and why it only appears in C++, as suggested by Justin Randall in the comments. 更新:关于整个extern "C"构造的目的的几句话,以及为什么它只出现在C ++中,正如Justin Randall在评论中所建议的那样。 Perhaps the leading reason why this is needed is that it prevents name mangling . 也许需要它的主要原因是它可以防止名称损坏 This is important when overloaded functions of the same name exist: mangled names are made unique, so these can be distinguished. 当存在相同名称的重载函数时,这很重要:错位名称是唯一的,因此可以区分这些名称。 On the other hand, there is no overloading in C, so no name mangling either and no need for the extern block. 另一方面,C中没有重载,因此没有名称重写,也不需要extern块。

Long story short, a typical C++ compiler would tend to rename a function like void f() , for example, to something like _Z1fv . 简而言之,典型的C ++编译器倾向于将像void f()这样的函数重命名为_Z1fv类的_Z1fv But the C compiler would look for f and fail. 但是C编译器会查找f并失败。 extern "C" makes the former use the same symbol name the latter would expect. extern "C"使前者使用后者所期望的相同符号名称。

More precise information can be found here . 可以在此处找到更精确的信息。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM