[英]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 constant
在MyClass.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"
使前者使用后者所期望的相同符号名称。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.