Tutorial: HowTo integrate a C++ library/class into a C programm

Emagine the situation: You have written a program in C and now you have the requirement to integrate an existing third parity C++ library into your program.

The C++ Library

The only thing you have is the class definition in the header file of the library:

MyClass.h
#ifndef __MYCLASS_H
#define __MYCLASS_H

class MyClass {
        private:
                int m_i;
        public:
                void int_set(int i);

                int int_get();
};

#endif

It is a simple class with only one member variable m_i and one setter and one getter method.

Perhaps you don't have the source code of the library, perhaps you only have a compiled version. To be able to reproduce the example here is the source of the class:

MyClass.cc
#include "MyClass.h"
void MyClass::int_set(int i) {
        m_i = i;
}

int MyClass::int_get() {
        return m_i;
}

To compile the class with GNU C++ comiler simply type:

g++ -c MyClass.cc -o MyClass.o

This gives you the object file that can be linked into your programm. In this place I won't explain how to create a complete library.

The C++ way

Just for comparison here a simple C++ program that uses our new class:

MyMain_c++.cc
#include "MyClass.h"
#include <iostream>

using namespace std;

int main(int argc, char* argv[]) {
        MyClass *c = new MyClass();
        c->int_set(3);
        cout << c->int_get() << endl;
        delete c;
}

This program can be compiled with:

g++ -c MyMain_c++.c -o MyMain_c++.o

And linked with:

g++ MyMain_c++.o MyClass.o -o MyMain_c++

Start the C++ program with:

./MyMain_c++

The Problem

If we want to access a C++ library from C code we have two problems that we have to solve:

The C-Wrapper

To solve these problems we have to write a C-wrapper around our C++ class. Our wrapper header file will be readable by the C and the C++ compiler.

MyWrapper.h
#ifndef __MYWRAPPER_H
#define __MYWRAPPER_H

#ifdef __cplusplus
extern "C" {
#endif

typedef struct MyClass MyClass;

MyClass* newMyClass();

void MyClass_int_set(MyClass* v, int i);

int MyClass_int_get(MyClass* v);

void deleteMyClass(MyClass* v);

#ifdef __cplusplus
}
#endif
#endif

The extern "C" {} statement tells the C++ compiler to use the C style name mangling so a C compiler will find the correct symbols in the object file later. The #ifdef __cplusplus contition is because the C compiler does not know the keyword extern.

For the C compiler we define a dummy class handler with typedef struct MyClass MyClass.

And then the constructor, method and destructor wrappers.

The following file is the wrapper code, written in C++, but with one important thing: it is defined as extern "C"!

MyWrapper.cc
#include "MyClass.h"
#include "MyWrapper.h"

extern "C" {
        MyClass* newMyClass() {
                return new MyClass();
        }

        void MyClass_int_set(MyClass* v, int i) {
                v->int_set(i);
        }

        int MyClass_int_get(MyClass* v) {
                return v->int_get();
        }

        void deleteMyClass(MyClass* v) {
                delete v;
        }
}

To compile the wrapper with GNU C++ comiler simply type:

g++ -c MyWrapper.cc -o MyWrapper.o

The C Program

Now we are ready to use the C++ class in our C code:

MyMain_c.c
#include "MyWrapper.h"
#include <stdio.h>

int main(int argc, char* argv[]) {
        struct MyClass* c = newMyClass();
        MyClass_int_set(c, 3);
        printf("%i\n", MyClass_int_get(c));
        deleteMyClass(c);
}

This program can be compiled with the C compiler:

gcc -c MyMain_c.cc -o MyMain_c.o

Note that the linking has to be done with the C++ comiler, a C linker like ldd does not work:

g++ MyMain_c.o MyWrapper.o MyClass.o -o MyMain_c

Start the C program with:

./MyMain_c

You should now get the same result as with your C++ program above.

I hope this mini tutorial helped you.