Подтвердить что ты не робот

"undefined ссылка на" ошибки при связывании статической библиотеки C с кодом С++

У меня есть тестовый файл (только для теста ссылок), где я перегружаю операторов new/delete своей собственной библиотекой malloc/free, называемой libxmalloc.a. Но я продолжаю получать "недооцененную ссылку" на ошибку, как указано при связывании статической библиотеки, даже меняя порядок test.o и -lxmalloc. Но все работает хорошо с другими программами C, связывающими эту библиотеку. Я настолько смущен этой проблемой и ценю любую подсказку.

Ошибка MSg:

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

Мой файл test.cpp:

#include <dual/xalloc.h>
#include <dual/xmalloc.h>
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;
}

Мой файл 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
4b9b3361

Ответ 1

Но все работает хорошо с другими программами C, связывающими эту библиотеку.

Вы заметили, что компиляция C и С++ создает разные имена символов на уровне объектных файлов? Он называется name mangling.
Линкером (С++) будет отображаться undefined ссылки в виде демарнированных символов в сообщении об ошибке, которые могут вас смутить. Если вы проверите свой test.o файл с помощью nm -u, вы увидите, что ссылочные имена символов не совпадают с именами, указанными в вашей библиотеке.

Если вы хотите использовать функции, связанные как внешние, которые были скомпилированы с использованием простого компилятора C, вам понадобятся объявления функций, заключенные в блок extern "C" {}, который подавляет кодирование имен С++ для всего, что было объявлено или определено внутри, например:

extern "C" 
{
    #include <dual/xalloc.h>
    #include <dual/xmalloc.h>
}

Более того, вы можете обернуть объявления функций в своих заголовочных файлах следующим образом:

#if defined (__cplusplus)
extern "C" {
#endif

/*
 * Put plain C function declarations here ...
 */ 

#if defined (__cplusplus)
}
#endif