I am trying to use extern "C" to be able to call a C++ class within a different C file. I can build this fine until I actually include the .h in the C file I want to call the C++ class from.
MyClass.cpp
MyClass::MyClass(){};
MyClass::~MyClass(){};
extern "C" void* MyClassInit(){
return new MyClass();
}
MyClass.h
extern "C" void* MyClassInit();
OK - the above compiles. But now I want to use MyClassInit in another .c file. As soon as I
#include "MyClass.h" in that file I get
error: expected identifier or '(' before string constant in MyClass.h where the externs are defined.
I assume I am missing some "if cplusplus" or another extern or something else very obscure.
There's no extern "C" in C: a C compiler won't understand this and will choke on it. You need to expose this directive to the C++ compiler only. This is why often in such headers you find this instead (a random example e.g. 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
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. 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.
Long story short, a typical C++ compiler would tend to rename a function like void f(), for example, to something like _Z1fv. But the C compiler would look for f and fail. extern "C" makes the former use the same symbol name the latter would expect.
More precise information can be found here.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With