2009-07-01 14 views
21

Ho una libreria c che uso in gcc. La libreria ha l'estensione .lib ma è sempre collegata come una libreria statica. Se scrivo un programma che usa la libreria come c-code, tutto come a-ok. Se tuttavia rinominare il file in .cpp (facendo cose semplici che funzionano in entrambi c/C++) ottengo riferimento indefinito. Questi sono piccoli programmi semplici che scrivo a scopo di test, quindi niente cose di fantasia. Compilare utilizzando:C-library non si collega usando gcc/g ++

gcc -g -Wall -I <path to custom headers> -o program main.c customlibrary.lib -lm -lpthread 

Quanto sopra funziona 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 provato a creare un collegamento simbolico denominato customlibrary.a ma senza fortuna.

Perché g ++ find non riconosce la mia libreria. Sfortunatamente non ho accesso al codice sorgente delle librerie ma collegare un c-lib a C++ non dovrebbe essere un problema, giusto?

risposta

37

La libreria sembra avere un'API che presuppone che venga chiamata da C, non da C++. Questo è importante perché C++ richiede effettivamente che i simboli esportati da una libreria contengano più informazioni rispetto al solo nome della funzione. Questo è gestito da "nome mangling" delle funzioni.

Presumo che la libreria abbia un file di inclusione che dichiari la sua interfaccia pubblica. Per renderlo compatibile sia con C che con C++, dovresti fare in modo di dire a un compilatore C++ che le funzioni che dichiara debbano essere utilizzate per usare il collegamento e la denominazione di C.

Una risposta semplice probabilità di verificare questo è quello di fare questo:

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 la successiva in prossimità del fondo:

#ifdef __cplusplus 
} 
#endif 
+1

Il simbolo '__cplusplus' ha due sottolineature, come definito dalle norme pertinenti. – RBerteig

2

il vostro file di intestazione ha il solito

#ifdef __cplusplus 
extern "C" { 
#endif 

// ... 

#ifdef __cplusplus 
} /* extern "C" */ 
#endif 

per dare la Li brary functions C linkage esplicitamente.

. I file cpp sono compilati con collegamento C++, ad esempio il nome mangling per impostazione predefinita.

4

Il compilatore C++ esegue ciò che è noto come manomissione dei nomi: i nomi visualizzati nel codice non sono gli stessi visualizzati dal linker. 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 lo fanno per un intero file di intestazione:

// myfile.cpp 
extern "C" { 
    #include "mylibdefs.h"  // defs for your C library functions 
} 
Problemi correlati