Esto no es demasiado difícil de hacer a mano, pero dependerá del tamaño de su interfaz. Los casos en los que lo hice fueron para permitir el uso de nuestra biblioteca C ++ desde el código C puro y, por lo tanto, SWIG no fue de mucha ayuda. (Bueno, tal vez SWIG pueda usarse para hacer esto, pero no soy un gurú de SWIG y no parecía trivial)
Todo lo que terminamos haciendo fue:
- Cada objeto pasa en C por un asa opaca.
- Los constructores y destructores están envueltos en funciones puras
- Las funciones miembro son funciones puras.
- Otras incorporaciones se asignan a equivalentes de C cuando es posible.
Entonces, una clase como esta (encabezado C ++)
class MyClass
{
public:
explicit MyClass( std::string & s );
~MyClass();
int doSomething( int j );
}
Se asignaría a una interfaz C como esta (encabezado 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 );
La implementación de la interfaz se vería así (fuente 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);
}
}
Derivamos nuestro identificador opaco de la clase original para evitar la necesidad de conversión, y (Esto no parece funcionar con mi compilador actual). Tenemos que convertir el identificador en una estructura, ya que C no admite clases.
Eso nos da la interfaz C básica. Si desea un ejemplo más completo que muestre una forma en que puede integrar el manejo de excepciones, puede probar mi código en github: https://gist.github.com/mikeando/5394166
La parte divertida ahora es asegurarse de que obtenga todas las bibliotecas de C ++ necesarias vinculadas correctamente a su biblioteca más grande. Para gcc (o clang) eso significa simplemente hacer la etapa de enlace final usando g ++.