Wrapping C++ class API for C consumption Wrapping C++ class API for C consumption c c

Wrapping C++ class API for C consumption


Foreach public method you need a C function.
You also need an opaque pointer to represent your class in the C code.
It is simpler to just use a void* though you could build a struct that contains a void* and other information (For example if you wanted to support arrays?).

Fred.h--------------------------------#ifdef  __cplusplusclass Fred{    public:    Fred(int x,int y);    int doStuff(int p);};#endif//// C Interface.typedef void*   CFred;//// Need an explicit constructor and destructor.extern "C" CFred  newCFred(int x,int y);extern "C" void   delCFred(CFred);//// Each public method. Takes an opaque reference to the object// that was returned from the above constructor plus the methods parameters.extern "C" int    doStuffCFred(CFred,int p);

The the implementation is trivial.
Convert the opaque pointer to a Fred and then call the method.

CFred.cpp--------------------------------// Functions implemented in a cpp file.// But note that they were declared above as extern "C" this gives them// C linkage and thus are available from a C lib.CFred newCFred(int x,int y){    return reinterpret_cast<void*>(new Fred(x,y));}void delCFred(CFred fred){    delete reinterpret_cast<Fred*>(fred);}int doStuffCFred(CFred fred,int p){    return reinterpret_cast<Fred*>(fred)->doStuff(p);}


While Loki Astari's answer is very good, his sample code puts the wrapping code inside the C++ class. I prefer to have the wrapping code in a separate file. Also I think it is better style to prefix the wrapping C functions with the class name.

The following blog posts shows how to do that:http://blog.eikke.com/index.php/ikke/2005/11/03/using_c_classes_in_c.html

I copied the essential part because the blog is abandoned and might finally vanish (credit to Ikke's Blog):


First we need a C++ class, using one header file (Test.hh)

class Test {    public:        void testfunc();        Test(int i);    private:        int testint;};

and one implementation file (Test.cc)

#include <iostream>#include "Test.hh"using namespace std;Test::Test(int i) {    this->testint = i;}void Test::testfunc() {    cout << "test " << this->testint << endl;}

This is just basic C++ code.

Then we need some glue code. This code is something in-between C and C++. Again, we got one header file (TestWrapper.h, just .h as it doesn't contain any C++ code)

typedef void CTest;#ifdef __cplusplusextern "C" {#endifCTest * test_new(int i);void test_testfunc(const CTest *t);void test_delete(CTest *t);#ifdef __cplusplus}#endif

and the function implementations (TestWrapper.cc, .cc as it contains C++ code):

#include "TestWrapper.h"#include "Test.hh"extern "C" {    CTest * test_new(int i) {        Test *t = new Test(i);        return (CTest *)t;    }    void test_testfunc(const CTest *test) {        Test *t = (Test *)test;        t->testfunc();    }    void test_delete(CTest *test) {        Test *t = (Test *)test;        delete t;    }}


First, you might not need to convert all your methods to C functions. If you can simplify the API and hide some of the C++ interface, it is better, since you minimize the chance to change the C API when you change C++ logic behind.

So think of a higher level abstraction to be provided through that API. Use that void* solution you described. It looks to me the most appropriate (or typedef void* as HANDLE :) ).