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 на С++ не должна быть проблемой?
Ответы
Ответ 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, т.е. смены имени по умолчанию.