Dies ist nicht allzu schwer von Hand zu tun, hängt jedoch von der Größe Ihrer Benutzeroberfläche ab. Die Fälle, in denen ich es getan habe, waren, die Verwendung unserer C ++ - Bibliothek aus reinem C-Code heraus zu ermöglichen, und daher war SWIG keine große Hilfe. (Nun, vielleicht kann SWIG verwendet werden, um dies zu tun, aber ich bin kein SWIG-Guru und es schien nicht trivial)
Am Ende haben wir nur Folgendes getan:
- Jedes Objekt wird in C einem undurchsichtigen Griff übergeben.
- Konstruktoren und Destruktoren sind in reine Funktionen eingeschlossen
- Mitgliedsfunktionen sind reine Funktionen.
- Andere Buildins werden nach Möglichkeit auf C-Äquivalente abgebildet.
Also eine Klasse wie diese (C ++ - Header)
class MyClass
{
public:
explicit MyClass( std::string & s );
~MyClass();
int doSomething( int j );
}
Würde einer C-Schnittstelle wie dieser zugeordnet werden (C-Header):
struct HMyClass;
typedef struct HMyClass HMyClass;
HMyClass * myStruct_create( const char * s );
void myStruct_destroy( HMyClass * v );
int myStruct_doSomething( HMyClass * v, int i );
Die Implementierung der Schnittstelle würde so aussehen (C ++ Quelle)
#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);
}
}
Wir leiten unseren undurchsichtigen Griff von der ursprünglichen Klasse ab, um zu vermeiden, dass ein Casting erforderlich ist, und (Dies schien mit meinem aktuellen Complier nicht zu funktionieren). Wir müssen das Handle zu einer Struktur machen, da C keine Klassen unterstützt.
Das gibt uns also die grundlegende C-Schnittstelle. Wenn Sie ein vollständigeres Beispiel wünschen, das eine Möglichkeit zeigt, die Ausnahmebehandlung zu integrieren, können Sie meinen Code auf github ausprobieren: https://gist.github.com/mikeando/5394166
Der unterhaltsame Teil besteht nun darin, sicherzustellen, dass alle erforderlichen C ++ - Bibliotheken korrekt mit Ihrer größeren Bibliothek verknüpft sind. Für gcc (oder clang) bedeutet dies, dass nur die letzte Verbindungsphase mit g ++ durchgeführt wird.