Pregunta

Me parece como una obviedad, pero no puedo encontrar ninguna información en contra o por ella.

Desde el punto de vista de desenredo etc, supongo que no se trata de un gran problema, pero no puedo averiguar, cómo puedo escribir un poco pequeño programa C que llama a una función de una diminuta C ++ biblioteca.

Estoy en Linux en este momento, tratando con estática vinculante.

Esto debe ser algo que mucha gente está corriendo en muchos libros o la cubierta, pero me siento como un Gump ciego sentado frente a este problema. Curiosamente, no hay tal cuestión en SO tampoco.

Yo ni siquiera sé si este trabajo lata, mucho menor cómo esto se tiene que hacer.

¿Fue útil?

Solución

Por lo general, es necesario forzar al compilador de C ++ para construir la biblioteca con C vinculación de las funciones exportadas.

Se puede hacer que al hacer lo siguiente a su cabecera:

#ifdef __cplusplus
extern "C" {
#endif

void func(void);

/* ... Other function defs go here ... */

#ifdef __cplusplus
}
#endif

Normalmente, el enlazador hará C ++ nombre-mangling a las funciones, por lo que el enlazador C no será capaz de encontrarlos. extern "C" fuerzas que no lo haga eso. Es necesario que envolverlo en el #ifdef, porque extern "C" no es válido en C.

Actualizar

Como Charles Salvia dice en un comentario más abajo, es necesario asegurarse de que no hay excepciones hacen su camino a través de su interfaz, debido a que C no tiene manera de manejar ellos (al menos no de una manera independiente de la plataforma).

Otros consejos

Si la biblioteca de C ++ no proporciona una interfaz de C, entonces no se puede.

Si lo hace, interfaz de uso C.

Si usted es el autor, utilice la función extern "C". http://www.parashift.com/c++-faq -Lite / mezcla-c-y-cpp.html

En lo personal, me gustaría escribir un archivo de C ++ que exporta funciones que el uso C vinculación. En otras palabras, escribir un enlace.

En Linux, se puede obtener el nombre revuelto de sus funciones de C ++ con el comando

nm my-tiny-c++lib.a

llamar a la función de C por él es destrozado nombre, pero no espere que este truco para ser portátil ...

Editar a continuación, usted tiene que enlace usando g ++ o con gcc -lstdc ++

Es un problema desde el punto de desenredo. Uso extern C alrededor del C ++ al que desea llamar de C.

y para dar no se ha normalizado en C ++, mangling-de puesto que se consideró demasiado dependiente de la plataforma . El resultado es, que si bien se podría averiguar el nombre del método de un método C ++ mirando a la salida de enlazador, no hay manera portátil de encontrar el nombre enlazable "real" de un método de función de C ++.

Se puede escribir un envoltorio de C alrededor de cualquier biblioteca de C ++ que tiene una API C ++. La envoltura debe ser escrito en C ++.

Se puede incluso utilizar sus clases de C ++. Usted hacia delante se declaran como estructura. Algunos compiladores darán una advertencia si usted hace esto, pero es probable que pueda o bien desactivar esta advertencia o simplemente ignorarlo.

Ahora cree libres funciones para crear un puntero a una estructura tal (no es un ejemplo, ya que no ve su definición completa) y disponer de un tal puntero y todos sus métodos, tomando como parámetro.

Tenga en cuenta que si la clase está en un espacio de nombres, usted no será capaz de hacer esto para crear su propia estructura que acaba de ese miembro y el uso que "envoltorio" en su lugar.

Para todas sus funciones C. en la cabecera única, puesto

#ifdef __cplusplus
extern "C" {
#endif

// all your functions

#ifdef __cplusplus
}
#endif

miradas de envoltorio típica de esta manera:

---- ---- class_a.hpp

#include "class_a_wrapper"

class A {
     public:
     int foo(double p);
     double bar(int x, int y);
}

---- ---- class_a_wrapper.h

#ifdef __cplusplus
extern "C" {
#endif

struct wrap_A;
int wrap_A_foo(struct wrap_A *obj, double p);
double wrap_A_bar(struct wrap_A *obj, int x, int y);

#ifdef __cplusplus
}
#endif

---- ---- class_a_wrapper.cpp

#include "class_a.hpp"

int wrap_A_foo(struct wrap_A *obj, double p) {
    return (static_cast<A*>obj)->foo(p);
}
double wrap_A_bar(struct wrap_A *obj, int x, int y) {
    return (static_cast<A*>obj)->bar(x, y);
}
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top