“Riferimento non definito a” errori durante il collegamento di librerie C statiche con codice C ++

Ho un file di test (solo per il test del link) dove sovraccarico gli operatori new / delete con la mia libreria malloc / free chiamata libxmalloc.a. Ma continuo a ricevere l’errore “riferimento indefinito a” come segue quando collego la libreria statica, anche io cambio l’ordine di test.o e -lxmalloc. Ma tutto funziona bene con altri programmi C che collegano questa libreria. Sono così confuso con questo problema e apprezzo qualsiasi idea.

Errore:

g++ -m64 -O3 -I/usr/include/ethos -I/usr/include/nacl/x86_64 -c -o test.o test.cpp g++ -m64 -O3 -L. -o demo test.o -lxmalloc test.o: In function `operator new(unsigned long)': test.cpp:(.text+0x1): undefined reference to `malloc(unsigned long)' test.o: In function `operator delete(void*)': test.cpp:(.text+0x11): undefined reference to `free(void*)' test.o: In function `operator new[](unsigned long)': test.cpp:(.text+0x21): undefined reference to `malloc(unsigned long)' test.o: In function `operator delete[](void*)': test.cpp:(.text+0x31): undefined reference to `free(void*)' test.o: In function `main': test.cpp:(.text.startup+0xc): undefined reference to `malloc(unsigned long)' test.cpp:(.text.startup+0x19): undefined reference to `malloc(unsigned long)' test.cpp:(.text.startup+0x24): undefined reference to `free(void*)' test.cpp:(.text.startup+0x31): undefined reference to `free(void*)' collect2: ld returned 1 exit status make: *** [demo] Error 1 

Il mio file test.cpp:

 #include  #include  void* operator new (size_t sz) { return malloc(sz); } void operator delete (void *ptr) { free(ptr); } void* operator new[] (size_t sz) { return malloc(sz); } void operator delete[] (void *ptr) { free(ptr); } int main(void) { int *iP = new int; int *aP = new int[3]; delete iP; delete[] aP; return 0; } 

Il mio makefile:

 CFLAGS += -m64 -O3 -I/usr/include/ethos -I/usr/include/nacl/x86_64 CXXFLAGS += -m64 -O3 LIBDIR += -L. LIBS += -lxmalloc all: demo demo: test.o $(CXX) $(CXXFLAGS) $(LIBDIR) -o demo test.o $(LIBS) test.o: test.cpp $(CXX) $(CFLAGS) -c -o [email protected] $< clean: - rm -f *.o demo 

Ma tutto funziona bene con altri programmi C che collegano questa libreria.

Hai notato che la compilazione C e C ++ crea nomi di simboli diversi a livello di file object? Si chiama ‘ nome mangling ‘.
Il linker (C ++) mostrerebbe i riferimenti non definiti come simboli demansionati nel messaggio di errore, che potrebbe confondervi. Se controlli il tuo file test.o con nm -u vedrai che i nomi dei simboli di riferimento non corrispondono a quelli forniti nella tua libreria.

Se vuoi usare le funzioni collegate come esterni che sono state compilate usando il compilatore C semplice, avrai bisogno delle loro dichiarazioni di funzione racchiuse in un blocco extern "C" {} externale che sopprime il nome del nome C ++ per tutto ciò che è dichiarato o definito all’interno, ad esempio:

 extern "C" { #include  #include  } 

Ancora meglio, potresti avvolgere le dichiarazioni di funzione nei tuoi file di intestazione in questo modo:

 #if defined (__cplusplus) extern "C" { #endif /* * Put plain C function declarations here ... */ #if defined (__cplusplus) } #endif