У меня есть библиотека C ++, которая предоставляет различные классы для управления данными. У меня есть исходный код библиотеки.
Я хочу расширить API C ++ для поддержки вызовов функций C, чтобы библиотеку можно было использовать с кодом C и кодом C ++ одновременно.
Я использую цепочку инструментов GNU (gcc, glibc и т. Д.), Поэтому поддержка языка и архитектуры не является проблемой.
Есть ли причины, по которым это технически невозможно?
Есть ли какие-то проблемы, которых мне нужно остерегаться?
Есть ли по этому поводу ресурсы, примеры кода и / или документация?
Еще кое-что, что я выяснил:
- Используйте следующее, чтобы обернуть заголовки C ++, которые должны использоваться кодом C.
#ifdef __cplusplus
extern "C" {
#endif
//
// Code goes here ...
//
#ifdef __cplusplus
} // extern "C"
#endif
- Храните «настоящие» интерфейсы C ++ в отдельных файлах заголовков, которые не включены в C. Подумайте о принципе PIMPL . Использование
#ifndef __cplusplus #error
вещей помогает здесь обнаружить любое безумие. - Осторожно с идентификаторами C ++ как именами в коде C
- Перечисления различаются по размеру в компиляторах C и C ++. Возможно, это не проблема, если вы используете цепочку инструментов GNU, но все же будьте осторожны.
Для структур используйте следующую форму, чтобы не запутать C.
typedef struct X { ... } X
Затем используйте указатели для передачи объектов C ++, их просто нужно объявить в C как struct X, где X - объект C ++.
Все это любезно предоставил друг, который специализируется на C ++.
Ответы:
Да, конечно, это возможно. Вам нужно будет написать уровень интерфейса на C ++, который объявляет функции с
extern "C"
:Затем вы вызовете
foo()
из своего модуля C, который передаст вызовrealFoo()
функции, реализованной на C ++.Если вам нужно предоставить полный класс C ++ с элементами данных и методами, вам может потребоваться больше работы, чем этот простой пример функции.
источник
extern "C"
размещать только в объявлениях (а не в определениях)? Поскольку вы упомянули «уровень, объявляющий функции», но ваш пример кода также является определением. Другими словами, следует ли размещать его в файлах заголовков или исходных файлах? (Или в обоих?)extern "C"
туда поместить . Ваш компилятор сообщит вам, нужно ли вам также добавить его в определение.C ++ FAQ Lite: «Как смешивать код C и C ++» .
Некоторые ошибки описаны в ответах на эти вопросы:
источник
Основная проблема: исключения не могут быть перехвачены в C.Если есть вероятность возникновения исключения в коде C ++, очень осторожно напишите свой код C или свои оболочки C ++. И наоборот, механизмы, подобные исключениям (например, longjump) в коде C (как в различных языках сценариев), не требуются для вызова деструкторов для объектов C ++ в стеке.
источник
вы можете смешивать код C / C ++. Если ваша функция main () на C ++, вам просто нужно убедиться, что ваши функции c объявлены
Если ваш main - C, то вы, вероятно, в порядке, за исключением статических переменных. Любые конструкторы с вашими статическими переменными должны вызываться перед запуском main (). Этого не произойдет, если C - ваш main. Если у вас много статических переменных, лучше всего заменить статические переменные одиночными.
источник