Использование библиотеки C ++ в коде C - PullRequest
96 голосов
/ 14 октября 2008

У меня есть библиотека C ++, которая предоставляет различные классы для управления данными. У меня есть исходный код для библиотеки.

Я хочу расширить API C ++ для поддержки вызовов функций C, чтобы библиотека могла использоваться одновременно с кодом C и кодом C ++.

Я использую цепочку инструментов GNU (gcc, glibc и т. Д.), Поэтому поддержка языка и архитектуры не является проблемой.

Есть ли причины, по которым это технически невозможно?

Есть ли какие-нибудь гоча , за которыми мне нужно следить?

Имеются ли ресурсы, пример кода и / или документация по этому вопросу?


Некоторые другие вещи, которые я обнаружил:

  1. Используйте следующую команду, чтобы обернуть заголовки C ++, которые должны использоваться кодом C.

#ifdef __cplusplus
extern "C" {  
#endif  
//  
// Code goes here ...  
//  
#ifdef __cplusplus  
} // extern "C"  
#endif
  1. Храните «настоящие» интерфейсы C ++ в отдельных заголовочных файлах, которые не включены в C. Подумайте Принцип PIMPL здесь. Использование #ifndef __cplusplus #error помогает здесь обнаружить сумасшествие.
  2. Осторожно идентификаторы C ++ как имена в коде C
  3. Переменные, различающиеся по размеру между компиляторами C и C ++. Возможно, это не проблема, если вы используете цепочку инструментов GNU, но все же будьте осторожны.
  4. Для структур следуйте следующей форме, чтобы C не запутался.

    typedef struct X { ... } X
    
  5. Затем используйте указатели для передачи объектов C ++, их просто нужно объявить в C как struct X, где X - объект C ++.

Все это любезно предоставлено другом, волшебником в C ++.

Ответы [ 4 ]

66 голосов
/ 14 октября 2008

Да, это, конечно, возможно. Вам нужно будет написать интерфейсный слой на C ++, который объявляет функции с extern "C":

extern "C" int foo(char *bar)
{
    return realFoo(std::string(bar));
}

Затем вы вызовете foo() из вашего модуля C, который передаст вызов функции realFoo(), которая реализована в C ++.

Если вам нужно предоставить полный класс C ++ с членами и методами данных, то вам, возможно, потребуется выполнить больше работы, чем в этом простом примере функции.

21 голосов
/ 14 октября 2008

C ++ FAQ Lite: "Как смешать код C и C ++" .

Некоторые вопросы описаны в ответах на эти вопросы:

  • [32.8] Как передать объект класса C ++ в / из функции C?
  • [32.9] Может ли моя функция C напрямую обращаться к данным в объекте класса C ++?
11 голосов
/ 14 октября 2008

Основная проблема: исключения не могут быть перехвачены в C. Если есть вероятность возникновения исключения в коде C ++, либо очень тщательно напишите свой код C или оболочки C ++. И наоборот, механизмы, подобные исключениям (например, longjump) в коде C (как это встречается в различных языках сценариев), не обязаны вызывать деструкторы для объектов C ++ в стеке.

3 голосов
/ 14 октября 2008

вы можете смешивать код C / C ++. Если ваша функция main () в C ++, то вам просто нужно убедиться, что ваши функции c объявлены

extern "C"

Если ваш main - C, то вы, вероятно, в порядке, за исключением статических переменных. Предполагается, что любые конструкторы с вашими статическими переменными должны вызываться до запуска main (). Этого не произойдет, если C ваш главный. Если у вас много статических переменных, лучше всего заменить статические переменные на одиночные.

...