Alex Rivera | Logout

Developing C wrapper API for Object-Oriented C++ code

Asked 2010-01-11T23:47:23.863
101

I'm looking to develop a set of C APIs that will wrap around our existing C++ APIs to access our core logic (written in object-oriented C++). This will essentially be a glue API that allows our C++ logic to be usable by other languages. What are some good tutorials, books, or best-practices that introduce the concepts involved in wrapping C around object-oriented C++?

Edit
Report

2 Answers

86

This is not too hard to do by hand, but will depend on the size of your interface. The cases where I've done it were to enable use of our C++ library from within pure C code, and thus SWIG was not much help. (Well maybe SWIG can be used to do this, but I'm no SWIG guru and it seemed non-trivial)

All we ended up doing was:

  1. Every object is passed about in C an opaque handle.
  2. Constructors and destructors are wrapped in pure functions
  3. Member functions are pure functions.
  4. Other builtins are mapped to C equivalents where possible.

So a class like this (C++ header)

class MyClass
{
  public:
  explicit MyClass( std::string & s );
  ~MyClass();
  int doSomething( int j );
}

Would map to a C interface like this (C header):

struct HMyClass; // An opaque type that we'll use as a handle
typedef struct HMyClass HMyClass;
HMyClass * myStruct_create( const char * s );
void myStruct_destroy( HMyClass * v );
int myStruct_doSomething( HMyClass * v, int i );

The implementation of the interface would look like this (C++ source)

#include "MyClass.h"

extern "C" 
{
  HMyClass * myStruct_create( const char * s )
  {
    return reinterpret_cast<HMyClass*>( new MyClass( s ) );
  }
  void myStruct_destroy( HMyClass * v )
  {
    delete reinterpret_cast<MyClass*>(v);
  }
  int myStruct_doSomething( HMyClass * v, int i )
  {
    return reinterpret_cast<MyClass*>(v)->doSomething(i);
  }
}

We derive our opaque handle from the original class to avoid needing any casting, and (This didn't seem to work with my current compiler). We have to make the handle a struct as C doesn't support classes.

So that gives us the basic C interface. If you want a more complete example showing one way that you can integrate exception handling, then you can try my code on github : answered 2010-01-12T00:09:50.980

4

Just replace the concept of an object with a void * (often referred to as an opaque type in C oriented libraries) and reuse everything you know from C++.

answered 2010-01-12T00:05:00.773

Your Answer