2017-01-15 13 views
0

Я пишу библиотеку C++ и теперь разрабатываю API стиля C. Теперь у меня есть куча методов, которые используют одноплодные основной класс, здесь упрощено заявление:Способ использования общего класса между API экспорта стиля C в C++ DLL

extern "C" { 
    MYDLL_API void getAudioDeviceList(); 
    MYDLL_API void getWindowList(); 

    MYDLL_API uint32_t BeginVideoCapture(); 
    MYDLL_API uint32_t StopVideoCapture(); 
} 

Но до сих пор я решил удалить одиночка, там дилемму. Что является самым элегантным способом использования моего класса через вызовы API? Сейчас я вижу только один способ, с помощью глобальной переменной и инициализации метод, как (где CVideoConverter это C структура обруча под C++ класс):

extern "C" { 
    CVideoConverter* t = new CVideoConverter(); 

    MYDLL_API void getAudioDeviceList(); 
    MYDLL_API void getWindowList(); 

    MYDLL_API uint32_t BeginVideoCapture(); 
    MYDLL_API uint32_t StopVideoCapture(); 
} 

Или я должен создать некоторые C структуру, которая будет содержать все методы API и указатель на объект CVideoConverter, который сам экспортирует структуру. Жду ваших предложений, спасибо!

+0

Чтобы помочь вам, нам нужно больше информации о связи между вашим класс 'CVideoConverter' и DLL функций. Как вы использовали точку входа 'DllMain()' и сообщения DLL_PROCESS_ATTACH'/'DLL_PROCESS_DETACH'? –

ответ

0

Один хороший подход (а не единственный) - это предоставить фабричную функцию экземпляра вашего класса CVideoConverter, которая вернет транстипный экземпляр C через reinterpret_cast. Таким образом, вы можете вызвать свою экспортированную C-функцию, предоставив эту ссылку экземпляра в качестве 1-го параметра. На стороне DLL вы retranstype в экземпляр C++ и вызываете метод вашего экземпляра.

Пожалуйста, перейдите по этой ссылке, которая содержит более подробные объяснения и очень хорошие примеры.

C++ DLL to be used in C program

1

Определение глобальной переменной в заголовочном файле никогда не будет вести к счастью. Вместо этого, если вы хотите использовать C API для своего кода на C++, я рекомендую вам фактически посмотреть на FILE и стандартные функции обработки файлов C.

FILE тип-алиас непрозрачная структура, вы не знаете его содержимого, и вам также не нужно заботиться. Вместо этого у вас есть функция, которая выделяет экземпляр вашей непрозрачной структуры и возвращает указатель на нее. Затем все ваши функции API C принимают этот указатель в качестве аргумента.

Какая это непрозрачная структура на самом деле? Это не имеет большого значения, это может быть просто частная структура, содержащая экземпляр вашего основного класса. Тогда функции C API, которые имеют полное определение структуры и классов), могут использовать ее для вызова необходимых функций-членов.


Маленький и простой пример:

общественности заголовок файла, который является то, что приложения C должны включать в себя:

#ifndef MY_C_API_H 
#define MY_C_API_H 

#ifdef __cplusplus 
extern "C" { 
#endif 

// Forward declaration of the MYSTRUCT structure, and definition of type-alias 
typedef struct MYSTRUCT MYSTRUCT; 

MYSTRUCT *my_create(void); 
void my_destroy(MYSTRUCT *mystruct); 
void my_do_something(MYSTRUCT *mystruct, int some_argument); 

#ifdef __cplusplus 
} 
#endif 

#endif // End of header include guard 

частный файл заголовок , который будет использоваться только вашим приложением только:

#ifndef MY_PRIVATE_H 
#define MY_PRIVATE_H 

#include "my_c_api.h" 
#include "my_class.h" 

struct MYSTRUCT 
{ 
    MyClass my_object; 
}; 

#endif 

Реализация C API:

#include "my_private.h" 

extern "C" 
{ 
    MYSTRUCT *my_create(void) 
    { 
     return new MYSTRUCT; 
    } 

    void my_destroy(MYSTRUCT *mystruct) 
    { 
     delete mystruct; 
    } 

    void my_do_something(MYSTRUCT *mystruct, int some_argument) 
    { 
     mystruct->my_object.do_something(some_argument); 
    } 
}