Nie jest to zbyt trudne do zrobienia ręcznie, ale zależy to od rozmiaru interfejsu. Przypadki, w których to zrobiłem, polegały na umożliwieniu korzystania z naszej biblioteki C ++ z poziomu czystego kodu C, a zatem SWIG nie był zbyt pomocny. (Cóż, może SWIG może być do tego użyty, ale nie jestem guru SWIG i wydawało się to nietrywialne)
Skończyło się na tym, że:
- Każdy obiekt jest przekazywany w języku C przez nieprzezroczysty uchwyt.
- Konstruktory i destruktory są opakowane w czyste funkcje
- Funkcje składowe są funkcjami czystymi.
- Inne polecenia wbudowane są mapowane na odpowiedniki języka C.
Czyli taka klasa (nagłówek C ++)
class MyClass
{
public:
explicit MyClass( std::string & s );
~MyClass();
int doSomething( int j );
}
Zmapowałoby na interfejs C w ten sposób (nagłówek C):
struct HMyClass;
typedef struct HMyClass HMyClass;
HMyClass * myStruct_create( const char * s );
void myStruct_destroy( HMyClass * v );
int myStruct_doSomething( HMyClass * v, int i );
Implementacja interfejsu wyglądałaby następująco (źródło C ++)
#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);
}
}
Wyprowadzamy nasz nieprzezroczysty uchwyt z oryginalnej klasy, aby uniknąć konieczności odlewania i (To nie wydawało się działać z moim obecnym komplementem). Musimy uczynić uchwyt strukturą, ponieważ C nie obsługuje klas.
To daje nam podstawowy interfejs C. Jeśli potrzebujesz bardziej kompletnego przykładu pokazującego jeden sposób, w jaki możesz zintegrować obsługę wyjątków, możesz wypróbować mój kod na github: https://gist.github.com/mikeando/5394166
Zabawną częścią jest teraz upewnienie się, że wszystkie wymagane biblioteki C ++ są poprawnie połączone z większą biblioteką. W przypadku gcc (lub clang) oznacza to po prostu wykonanie ostatniego etapu linkowania za pomocą g ++.