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

C-библиотека, не связанная с использованием gcc/g++

У меня есть c-библиотека, которую я использую в gcc. Библиотека имеет расширение .lib, но всегда связано как статическая библиотека. Если я пишу программу, которая использует библиотеку как c-код, все как a-ok. Если я, однако, переименую файл в .cpp(делая простые вещи, которые работают как в c/С++), я получаю ссылку undefined. Это простые небольшие программы, которые я пишу для тестирования, так что ничего необычного. Я компилирую, используя:

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

Вышеизложенное работает как шарм. Однако:

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

или

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

приводит к undefined ссылке на любую функцию в customlibrary.lib. Я попытался создать символическую ссылку с именем customlibrary.a, но не повезло.

Почему g++ не распознает мою библиотеку. К сожалению, у меня нет доступа к исходному коду библиотек, но ссылка на c-lib на С++ не должна быть проблемой?

4b9b3361

Ответ 1

В вашей библиотеке есть API, который предполагает, что он будет вызываться из C, а не С++. Это важно, потому что С++ эффективно требует, чтобы символы, экспортированные из библиотеки, имели в них больше информации, чем просто имя функции. Это обрабатывается с помощью функции "name mangling".

Я предполагаю, что ваша библиотека имеет файл include, объявляющий его публичный интерфейс. Чтобы сделать его совместимым как с C, так и с С++, вам следует договориться сообщить компилятору С++, что функции, которые он объявляет, следует предполагать использовать C-ссылку и именование.

Вероятно, легкий ответ для проверки этого заключается в следующем:

extern "C" {
#include "customlibrary.h"
}

в вашем main.cpp вместо прямого включения customlibrary.h.

Чтобы сам заголовок работал на обоих языках и правильно объявлял его функции как C-like для С++, поставьте следующее в верхней части заголовочного файла:

#ifdef __cplusplus
extern "C" {
#endif

и ниже внизу:

#ifdef __cplusplus
}
#endif

Ответ 2

Компилятор С++ выполняет так называемое управление именами - имена, которые появляются в вашем коде, не совпадают с именами вашего компоновщика. Обычный способ заключается в том, чтобы сообщить компилятору, что некоторым функциям требуется C-связь:

// myfile.cpp
extern "C" int libfun();    // C function in your library

или сделать это для всего файла заголовка:

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

Ответ 3

Имеет ли ваш заголовочный файл обычный

#ifdef __cplusplus
extern "C" {
#endif

// ...

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

чтобы явно передать функции библиотеки C.

.cpp файлы скомпилированы с помощью С++ linkage, т.е. смены имени по умолчанию.