3

PLEASE before closing as dupe, read the question & see why it is different (hint: it's the C compiler)

I have Googled and found many, many, explanations of how a C function can call a C++ member function.

They all look similar to the accepted answer to this question, from a very high rep member.

It says

In a header file, put

extern "C" void* MyClass_create() {
   return new MyClass;
}
extern "C" void MyClass_release(void* myclass) {
   delete static_cast<MyClass*>(myclass);
}
extern "C" void MyClass_sendCommandToSerialDevice(void* myclass, int cmd, int params, int id) {
   static_cast<MyClass*>(myclass)->sendCommandToSerialDevice(cmd,params,id);
}

and, in the C code, put

void* myclass = MyClass_create();
MyClass_sendCommandToSerialDevice(myclass,1,2,3);
MyClass_release(myclass);

That seems straightforward, but what I don't understand is that the header file is going to have to reference MyClass (never mind that static_cast), but I want to compile my C code with a C compiler (gcc), not a C++ compiler (g++).

It won't work. How can I call a C++ member function from C code - which is compiled with a C compiler?

7
  • 5
    The other answer doesn't say "In a header file, put". It says "Then inside C++ perform the function call:". The C compiler can only process the declarations, not the function definitions. Commented Apr 21, 2017 at 8:29
  • 1
    Put only the declarations in the header file, the definitions of those functions need to be compiled by the C++ compiler. Commented Apr 21, 2017 at 8:30
  • 3
    The question you linked is marked as a duplicate of another question where there is a detailed example explaining what should be put into the header and what into the C++ definition Commented Apr 21, 2017 at 8:37
  • 2
    Ok, I didn't read all of your question, sorry. You can compile your C code with a C compiler, but will have to compile the C++ code with a C++ compiler. The C compiler can understand void* MyClass_create(); and call that function. If the C++ compiler sees the function as extern "C" void* MyClass_create(); it will make the call from C work. Commented Apr 21, 2017 at 8:37
  • 1
    The key point here is that you cannot call the member function with a C compiler. Maybe I should have been clearer, you implement a C++ function with a C interface that is callable from C, and that implementation does the C++ call. Note that it is inherently impossible to call a C++ member function from a C compiler, the compiler would have to parse the class and understand it, know how to call a member function... be a C++ compiler. Commented Apr 21, 2017 at 10:31

1 Answer 1

5

You should do the following in C++:

In a C-compatible header file, e.g. interface.h, write:

#if defined(__cplusplus)
extern "C" {
#endif

void* MyClass_create();
void MyClass_release(void* myclass);
void MyClass_sendCommandToSerialDevice(void* myclass, int cmd, int params, int id);

#if defined(__cplusplus)
}
#endif

and in a source file, e.g. interface.cpp, put

/*extern "C"*/ void* MyClass_create() {
    return new MyClass;
}
/*extern "C"*/ void MyClass_release(void* myclass) {
    delete static_cast<MyClass*>(myclass);
}
/*extern "C"*/ void MyClass_sendCommandToSerialDevice(void* myclass, int cmd, int params, int id) {
    static_cast<MyClass*>(myclass)->sendCommandToSerialDevice(cmd,params,id);
}

Now, compile these either as part of the original C++ library, or a separate C++ library. You should be able to include the above .h file in your pure C programs and link them against the library.

Sign up to request clarification or add additional context in comments.

1 Comment

A clear, excellent answer, which I have tested and am satisfied works (+1 and the answer).

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.