在 C++ DLL 中的 C 样式导出 API 之间使用公共 class 的方法
Way to use common class between C style exporting API in C++ DLL
我正在编写 C++ 库,现在正在为其设计 C 风格 API。现在我有一堆使用 main class 单例的方法,这里简化了声明:
extern "C" {
MYDLL_API void getAudioDeviceList();
MYDLL_API void getWindowList();
MYDLL_API uint32_t BeginVideoCapture();
MYDLL_API uint32_t StopVideoCapture();
}
但到目前为止我决定删除单例,出现了两难选择。通过 API 调用使用我的 class 最优雅的方法是什么?现在我只看到一种方法,使用全局变量和 init 方法,比如(其中 CVideoConverter 是 C struct wrap under C++ class):
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 对象的指针,导出结构本身。等待您的建议,谢谢!
一个好的方法(不是唯一的方法)是为您的 class CVideoConverter
提供实例工厂函数,它将 return 通过 reinterpret_cast
转换的 C 实例].这样,您可以通过提供此实例引用作为第一个参数来调用 C 导出的函数。在 DLL 端,您重新转换为 C++ 实例并调用实例的方法。
请关注此 link,其中提供了更详细的解释和非常好的示例。
C++ DLL to be used in C program
在头文件中定义全局变量永远不会带来幸福。相反,如果您想要 C++ 代码的 C API,我建议您实际查看 FILE
和标准 C 文件处理函数。
FILE
type-alias是一个不透明的结构,你不知道它的内容,也不应该关心。相反,你有一个函数分配你的不透明结构的实例和 returns 一个指向它的指针。然后你所有的 C API 函数都将这个指针作为参数。
这个不透明的结构到底是什么?这并不重要,它可以只是一个私有结构,其中包含您的 main class 的一个实例。然后具有完整结构定义的 C API 函数和 classes) 可以使用它来调用所需的成员函数。
一个简单的小例子:
public头文件,这是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
private 头文件,仅供您的应用程序内部使用:
#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);
}
}
我正在编写 C++ 库,现在正在为其设计 C 风格 API。现在我有一堆使用 main class 单例的方法,这里简化了声明:
extern "C" {
MYDLL_API void getAudioDeviceList();
MYDLL_API void getWindowList();
MYDLL_API uint32_t BeginVideoCapture();
MYDLL_API uint32_t StopVideoCapture();
}
但到目前为止我决定删除单例,出现了两难选择。通过 API 调用使用我的 class 最优雅的方法是什么?现在我只看到一种方法,使用全局变量和 init 方法,比如(其中 CVideoConverter 是 C struct wrap under C++ class):
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 对象的指针,导出结构本身。等待您的建议,谢谢!
一个好的方法(不是唯一的方法)是为您的 class CVideoConverter
提供实例工厂函数,它将 return 通过 reinterpret_cast
转换的 C 实例].这样,您可以通过提供此实例引用作为第一个参数来调用 C 导出的函数。在 DLL 端,您重新转换为 C++ 实例并调用实例的方法。
请关注此 link,其中提供了更详细的解释和非常好的示例。
C++ DLL to be used in C program
在头文件中定义全局变量永远不会带来幸福。相反,如果您想要 C++ 代码的 C API,我建议您实际查看 FILE
和标准 C 文件处理函数。
FILE
type-alias是一个不透明的结构,你不知道它的内容,也不应该关心。相反,你有一个函数分配你的不透明结构的实例和 returns 一个指向它的指针。然后你所有的 C API 函数都将这个指针作为参数。
这个不透明的结构到底是什么?这并不重要,它可以只是一个私有结构,其中包含您的 main class 的一个实例。然后具有完整结构定义的 C API 函数和 classes) 可以使用它来调用所需的成员函数。
一个简单的小例子:
public头文件,这是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
private 头文件,仅供您的应用程序内部使用:
#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);
}
}