2009-06-29 29 views
7

¿Hay una manera simple de trabajar con objetos C++ directamente desde C? Quiero exponer algunas clases de C++ a C o a FFI (interfaz de función externa). Claro, yo puedo escribir una cosas por el estilo:C++ código y objetos de C?

class Foo{ 
.... 
}; 

void *make_foo(...){ 
Foo *ptr = new Foo(..) 

return static_cast<void *>(ptr); 
} 

.. 

int *foo_method1(void *fooptr, ...){ 
Foo *ptr = static_cast<Foo*>(fooptr); 
} 

Pero hay un método más simple?

+0

¿Puedo preguntar qué tiene esto que ver con Lisp? – Svante

+0

Es una parte de una cuestión más general de exponer clases de C++ a Common Lisp a través de CFFI (o FFI dependiente de la implementación de lisp). –

Respuesta

8

Que, en general, es el método más simple.

Recuerde, también, que necesitará usar extern "C" en todos sus métodos de "envoltura" C, también.

7

Usted casi allí. Prefija sus funciones independientes con extern "C" para desactivar el compilador de C++ name mangling.

Por ejemplo:

extern "C" void *make_foo(...){ 
    Foo *ptr = new Foo(..) 

    return static_cast<void *>(ptr); 
} 
1

En realidad no hay una manera más sencilla de hacerlo. Puede usar SWIG para ir a otro idioma con tipos definidos por el usuario que son más que agregados de datos, pero al convertir a C tendrá que usar la idea de objetos de C.

1

Puede usar Verrazano/Fetter para generar enlaces CFFI para el código C++. Pero requiere GCC-XML y no estoy seguro acerca de su portabilidad.

1

Si es posible, entonces sus clases se derivan de una estructura. A continuación, puede utilizar punteros a esta estructura en el código C:

// C++ code 
extern "C" struct Cfoo {}; 
extern "C" struct Cbar {}; 

class foo : public Cfoo {}; 
class bar : public Cbar {}; 

// C API 
extern "C" { 
    struct Cfoo; 
    struct Cbar; 
} 

No es estrictamente un error, sin embargo gcc, al menos, advierte sobre la conversión entre los punteros con diferentes tipos.

void foo (void) { 
    struct Cfoo * pf; 
    struct Cbar * pb; 
    pf = pb;  // gcc warns 
} 

Si no puede heredar, a continuación, utilizar una idea similar, pero tienen la tienda de estructura C un puntero al objeto de C++, y de nuevo sólo declarar adelante las estructuras de la API C:

// C++ code 
class foo {}; 
class bar {}; 

extern "C" struct Cfoo { foo * pFoo; }; 
extern "C" struct Cbar { bar * pBar; }; 

// C API 
extern "C" { 
    struct Cfoo; 
    struct Cbar; 
} 

El La desventaja aquí es que la vida útil del objeto Cfoo y Cbar debe ser atendida.