Как вызвать функцию C++ от C?

Я знаю это.

Вызов C функционирует от C++:

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

//main.cpp

extern "C" void C_library_function(int x, int y);//prototype
C_library_function(2,4);// directly using it.

Это не исказило бы имя C_library_function и компоновщик нашел бы то же имя в его входе *.lib файлами, и проблема решена.

Вызывание функции C++ от C???

Но здесь я расширяю крупное приложение, которое записано в C, и я должен пользоваться библиотекой, которая записана в C++. Искажение имени C++ доставляет неприятности здесь. Компоновщик жалуется на неразрешенные символы. Хорошо я не могу использовать компилятор C++ по своему проекту C, потому что это повреждает партию другого материала. Каков выход?

По тому, как я использую MSVC

73
задан Jonathan Leffler 30 May 2016 в 06:30
поделиться

4 ответа

Вам нужно создать C API для раскрытия функциональности вашего C++ кода. По сути, вам нужно написать код на C++, который объявлен extern "C" и имеет чистый API на C (не используя классы, например), который обертывает библиотеку C++. Затем вы используете созданную вами библиотеку-обертку на чистом C.

Ваш C API может по желанию следовать объектно-ориентированному стилю, даже если C не является объектно-ориентированным. Например:

 // *.h file
 // ...
 #ifdef __cplusplus
 #define EXTERNC extern "C"
 #else
 #define EXTERNC
 #endif

 typedef void* mylibrary_mytype_t;

 EXTERNC mylibrary_mytype_t mylibrary_mytype_init();
 EXTERNC void mylibrary_mytype_destroy(mylibrary_mytype_t mytype);
 EXTERNC void mylibrary_mytype_doit(mylibrary_mytype_t self, int param);

 #undef EXTERNC
 // ...


 // *.cpp file
 mylibrary_mytype_t mylibrary_mytype_init() {
   return new MyType;
 }

 void mylibrary_mytype_destroy(mylibrary_mytype_t untyped_ptr) {
    MyType* typed_ptr = static_cast<MyType*>(untyped_ptr);
    delete typed_ptr;
 }

 void mylibrary_mytype_doit(mylibrary_mytype_t untyped_self, int param) {
    MyType* typed_self = static_cast<MyType*>(untyped_self);
    typed_self->doIt(param);
 }
82
ответ дан 24 November 2019 в 12:21
поделиться

Предполагая, что C++ API совместим с C (без классов, шаблонов и т. Д.), Вы можете обернуть его в extern "C" { ... } , точно так же, как вы делали, когда шли другим путем.

Если вы хотите предоставить объекты и другие симпатичные вещи C++, вам придется написать API-оболочку.

5
ответ дан 24 November 2019 в 12:21
поделиться

Вам нужно будет написать оболочку для C на C ++, если вы хотите это сделать. C ++ имеет обратную совместимость, но C не поддерживает прямую совместимость.

5
ответ дан 24 November 2019 в 12:21
поделиться

экспортируйте ваши функции C ++ как extern "C" (также известные как символы стиля C) или используйте формат файла .def для определения символов экспорта без декорирования для компоновщика C ++ когда он создает библиотеку C ++, компоновщик C не должен иметь проблем с ее чтением

2
ответ дан 24 November 2019 в 12:21
поделиться