Domanda

Mi sembra come un gioco da ragazzi, ma non riesco a trovare tutte le informazioni contro o per esso.

Dal punto di vista della demangling ecc, non credo che questo sia un grosso problema, ma non riesco a capire, come posso scrivere un po 'piccolo programma C che chiama una funzione da un po' piccola C ++ biblioteca.

Sono su linux in questo momento, provando con statico vincolante.

Questo deve essere qualcosa che molte persone sono in esecuzione in molti libri o di copertura, ma mi sento come un Gump cieco seduto di fronte a questo problema. È interessante notare che non esiste una domanda su SO sia.

Io non so nemmeno se questo può funzionare, di gran lunga inferiore come questo ha da fare.

È stato utile?

Soluzione

In genere, è necessario forzare il compilatore C ++ per costruire biblioteca collegamento C per le funzioni esportate.

Si può farlo effettuando le seguenti operazioni per l'intestazione:

#ifdef __cplusplus
extern "C" {
#endif

void func(void);

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

#ifdef __cplusplus
}
#endif

In genere, il linker farà C ++ nome-mutilazione alle funzioni, in modo che il linker C non sarà in grado di trovarli. extern "C" costringe di non farlo. Hai bisogno di avvolgerlo nel #ifdef, perché extern "C" non è valido C.

Aggiorna

Come Charles Salvia dice in un commento qui sotto, è necessario assicurarsi che non si smentisce mai si fanno strada attraverso l'interfaccia, in quanto C non ha modo di loro (almeno non un modo indipendente dalla piattaforma) gestione.

Altri suggerimenti

Se la libreria C ++ non fornisce un'interfaccia C, quindi non è possibile.

Se è così, l'interfaccia uso C.

Se sei l'autore, utilizzare la funzione extern "C". http://www.parashift.com/c++-faq -lite / mixing-c-e-cpp.html

Personalmente, mi piacerebbe scrivere un file C ++ che esporta funzioni che utilizzano C linkage. In altre parole, scrivere un vincolante.

Su Linux, è possibile ottenere il nome storpiato del C ++ funzioni con il comando

nm my-tiny-c++lib.a

Chiama la funzione da C per il suo nome storpiato, ma non aspettatevi questo trucco per essere portabile ...

Modifica : poi si deve collegamento mediante g ++, oppure con gcc -lstdc ++

Si tratta di un problema dal punto di demangling. Usa extern C intorno al C ++ che si desidera chiamare da C.

pressare e de-pressare non è mai stata standardizzata in C ++, in quanto si è ritenuto troppo dipendente dalla piattaforma . Il risultato è che, mentre si potrebbe capire il nome del metodo di un metodo C ++, cercando in uscita linker, non c'è modo portatile di trovare il "vero" nome collegabile di un metodo di funzione di C ++.

È possibile scrivere un wrapper C intorno a qualsiasi libreria C ++ che ha un'API C ++. L'involucro deve essere scritto in C ++.

È anche possibile utilizzare le classi C ++. È in avanti li dichiara come struct. Alcuni compilatori darà un avvertimento se si fa questo, ma probabilmente si può disabilitare o l'avviso o semplicemente ignorarlo.

È ora di creare liberi funzioni per creare un puntatore a tale struct (non un caso, come non si vede la sua piena definizione) e disporre di un tale puntatore e tutti i suoi metodi prendendo come parametro.

Si noti che se la classe è in uno spazio dei nomi, non si sarà in grado di fare questo in modo creare il proprio struct che ha proprio questo membro e l'uso che "wrapper", invece.

Per tutte le funzioni C. nell'intestazione solo, mettere

#ifdef __cplusplus
extern "C" {
#endif

// all your functions

#ifdef __cplusplus
}
#endif

tipici sguardi involucro come questo:

---- ---- 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);
}
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top