Я хочу использовать эту библиотеку C++ в C-коде (и скомпилировать код с gcc): https://github.com/fairlight1337/libcflie
Для этого я добавил функции Wrapper в CCrazyflie.h, CCrazyflie.cpp, CCrazyRadio.h и CCrazyRadio.cpp (все функции, которые я хочу использовать, находятся в этих файлах):
Добавлено в CCrazyRadio.h:
extern "C"
{
CCrazyRadio* newCCrazyRadio(string strRadioID);
void deleteCCrazyRadio(CCrazyRadio* cr);
int CCrazyRadio_startRadio(CCrazyRadio* cr);
}
Добавлено в CCrazyRadio.cpp:
extern "C"
{
CCrazyRadio* newCCrazyRadio(string strRadioID) {return new CCrazyRadio(strRadioID);}
void deleteCCrazyRadio(CCrazyRadio* cr) {delete cr;}
int CCrazyRadio_startRadio(CCrazyRadio* cr) {if(cr->startRadio()) return 1; else return 0;}
}
Я сделал то же самое для функций в CCrazyflie.h и CCrazyflie.cpp.
Я могу использовать обертки в C-коде, и они работают при компиляции с g++, но при компиляции с gcc компилятор жалуется, что он не знает iostream (включен в CCrazyflie.h и CCrazyRadio.h, которые включены в мой С-код).
Правильно ли я это делаю? Как я могу заставить gcc найти iostream (и другие C++ библиотеки, которые включены)? Если нужно, я был бы рад показать вам больше кода, я просто попытался оставить сообщение коротким.
Заранее благодарю за любую помощь! С уважением, Даниэль
Проблема заключается не в компоновщике, как предложили некоторые, или что обертки необходимо скомпилировать с помощью компилятора C++ (хотя они и есть).
Проблема заключается в том, что файл C содержит заголовок, который определяет обертки, а функции-обертки принимают типы, которые не имеют языка C, например, строка. Оператор extern
сообщает компилятору C++, чтобы он не мешал именам, но не волшебным образом ничего не делал внутри законченного C.
Таким образом, ваши функции обертки должны быть определены, чтобы взять типы C, поэтому ваш
CCrazyRadio* newCCrazyRadio(string strRadioID);
становится чем-то вроде
CCrazyRadio* newCCrazyRadio(char * radioId);
И внутренне к newCCrazyRadio вы можете построить string
для хранения вашего радиоидентификатора, если это необходимо. Если CCrazyRadio
- это класс, вы все равно будете иметь проблемы. Итак, если это только что возвращается как своего рода ручка, вы, возможно, можете заменить на void*
Вы по-прежнему нуждаетесь в extern 'C'
.
Вам также необходимо убедиться, что заголовок, содержащий функции обертки, ТОЛЬКО включает в себя файлы заголовков C. Даже если gcc (в режиме C) может их найти, они не будут содержать действительный код C. Это означает, что он не может включать iostream и т.д.
Еще одна вещь, я помню, что C не понимает синтаксис extern C
, поэтому вам может потребоваться обернуть это с помощью блока условной компиляции, например (вам нужно будет проверить синтаксис самостоятельно)
#ifdef _CPLUSPLUS_ // Check this bit
extern 'C'
{
#endif
//Put your prototype wrappers here
#ifdef _CPLUSPLUS
}
#endif
Это в основном означает, что только компилятор C++ увидит директиву extern C
(Обновление: этот ответ неверен из-за непонимания вопроса. Обсуждение в комментариях может все же быть достойным, хотя)
Это не то, с чем вы компилируете, это то, с чем вы связываетесь. Код C, скомпилированный с gcc, должен быть связан с g++, чтобы иметь доступ к системным библиотекам C++. Если какие-либо файлы.so или.lib в вашем проекте содержат код C++, вам необходимо установить связь с g++.
c
.