C-libreria non collega usando gcc / g ++
-
21-08-2019 - |
Domanda
Ho un c-biblioteca che io uso in GCC. La biblioteca ha la .lib estensione, ma è sempre legato come una libreria statica. Se scrivo un programma che utilizza la libreria come c-codice, tutto come un-ok. Se io però rinominare il file cpp (fare cose semplice che funziona sia in C / C ++) ottengo di riferimento definito. Si tratta di semplici piccoli programmi che scrivo a scopo di test in modo che nessun roba di fantasia. Compilo utilizzando:
gcc -g -Wall -I <path to custom headers> -o program main.c customlibrary.lib -lm -lpthread
I lavori di cui sopra come un fascino. Tuttavia:
g++ -g -Wall -I <path to custom headers> -o program main.cpp customlibrary.lib -lm -lpthread
o
gcc -g -Wall -I <path to custom headers> -o program main.cpp customlibrary.lib -lm -lpthread -lstdc++
risultati indefiniti riferimento ad una qualsiasi funzione customlibrary.lib. Ho cercato di creare un collegamento di nome simbolico customlibrary.a ma senza fortuna.
Perché non g ++ trovare riconosce la mia biblioteca. Purtroppo non ho accesso al codice sorgente delle librerie, ma il collegamento di un c-lib a C ++ non dovrebbe essere un problema giusto?
Soluzione
La vostra biblioteca sembra avere un'API che si assume che sarà chiamato da C, C ++ non. Questo è importante perché C ++ richiede effettivamente che i simboli esportati da una libreria hanno più informazioni in loro non solo il nome della funzione. Questo è gestito da "nome scempio" le funzioni.
I assumere la libreria dispone di un file di inclusione che dichiara la sua interfaccia pubblica. Per renderlo compatibile sia con C e C ++, si dovrebbe organizzare per raccontare un compilatore C ++ che le funzioni che dichiara dovrebbe essere assunto da utilizzare il collegamento e la denominazione di C.
Una risposta semplice probabilità di verificare questo è quello di fare in questo modo:
extern "C" {
#include "customlibrary.h"
}
nel main.cpp invece di appena compreso customlibrary.h
direttamente.
Per rendere l'intestazione stessa lavorano in entrambe le lingue e corretto dichiarare le sue funzioni come C-come C ++, inserire il seguente nella parte superiore del file di intestazione:
#ifdef __cplusplus
extern "C" {
#endif
e il seguente nella parte inferiore:
#ifdef __cplusplus
}
#endif
Altri suggerimenti
Il compilatore C ++ esegue ciò che è noto come il nome-mutilazione - i nomi che appaiono nel tuo codice non sono gli stessi come linker vede. Il modo normale intorno a questo è di informare il compilatore che alcune funzioni devono collegamento C:
// myfile.cpp
extern "C" int libfun(); // C function in your library
o farlo per un intero file di intestazione:
// myfile.cpp
extern "C" {
#include "mylibdefs.h" // defs for your C library functions
}
Il vostro file di intestazione avere il solito
#ifdef __cplusplus
extern "C" {
#endif
// ...
#ifdef __cplusplus
} /* extern "C" */
#endif
per dare il funzioni di libreria C legame esplicito.
file cpp sono compilati con C ++ legame nome cioè pressare per impostazione predefinita.