c++ - 类中 dll 的回调函数
问题描述
我编写了一个 c++ dll,它允许我从主应用程序注册一个回调函数。这是dll中的相应代码:
extern "C" {
typedef void(__stdcall* callbackRead_t)(UCHAR* Buffer, ULONG* BufferSize);
static callbackRead_t s_user_functionRead = nullptr; // variable used to store the user function address
__declspec(dllexport) void public_readfunc_taking_callback(callbackRead_t evHnd)
{
s_user_functionRead = evHnd; // save the callback address for funcA.
}
}
在主应用程序中,我像这样注册回调:
typedef void(__stdcall *TeventReadHS)(unsigned char* Buffer, unsigned long* BufferSize);
typedef void(__stdcall *eventReadHS)(TeventReadHS eveHnd);
void __stdcall ReadHSCallBack(unsigned char* Buffer, unsigned long* NumRead){
//do something
}
void __stdcall RegisterReadBack(void){
eventReadHS valr;
HINSTANCE handleHSC;
handleHSC=LoadLibrary(L"HSC.dll");
if (!handleHSC){
//Error handling here
}
valr=(eventReadHS)GetProcAddress(handleHSC,"public_readfunc_taking_callback");
if(valr!=NULL){
valr(&ReadHSCallBack);
}
}
这没有问题。但现在我希望 ReadHSCallBack 成为 Form1 类的成员。所以我将其更改为以下内容:
class TForm1: public TForm
{
//a lot of other stuff here
public:
__fastcall TForm1(TComponent* Owner);
void __fastcall TForm1::RegisterReadBack(void);
void __stdcall TForm1::ReadHSCallBack(unsigned char* Buffer, unsigned long* NumRead);
};
RegisterReadback 也获得 Form1 的成员:
void __fastcall TForm1::RegisterReadBack(void){
eventReadHS valr;
HINSTANCE handleHSC;
handleHSC=LoadLibrary(L"HSC.dll");
if (!handleHSC){
//Error handling here
}
valr=(eventReadHS)GetProcAddress(handleHSC,"public_readfunc_taking_callback");
if(valr!=NULL){
valr(&ReadHSCallBack);
}
}
我们开始了:它无法编译。导致错误的行是
valr(&ReadHSCallBack);
错误声明是:[bcc32 Error] Main.cpp(11422): E2034 Conversion of 'void (__stdcall * (_closure)(unsigned char *,unsigned long *))(unsigned char *,unsigned long *)' to 'void ( __stdcall *)(unsigned char *,unsigned long *)' 不可能。
我不知道如何处理该 __closure 声明。我也试过 valr(&this->ReadHSCallBack) 也没有帮助。
解决方案
除了使用函数指针,你可以使用 std::function 吗?
我一直对类方法进行回调,尽管我使用 lambdas。这是一个例子:
typedef std::function<void(const char *)> CallbackFunction;
这是一种传递符合该签名的东西的方法:
vec.addArg("port", [&](const char *arg){ port = atoi(arg); }, "p", "Set listen port. Default is 9300.");
到目前为止,这是从我目前正在处理的程序中剪切和粘贴的实际代码。lambda 可以做任何事情,所以我可以这样做:
vec.addArg("port", [=](const char *arg){ foo(arg); });
请注意,我使用 = 而不是 &。
你可以做整个 std::bind() 事情,但我觉得这很难看,宁愿传递一个 lambda。
使用 C 风格的函数指针非常像 C,C++ 程序员应该使用现代方法。这意味着 std::function 和可能的 lambdas。
推荐阅读
- r - 是否有任何适用的家庭成员可以在 R 中执行此操作?
- sql - 从数据库读取非常慢
- c - VSS C 编码打印出一棵圣诞树
- go - 关于映射、字符串指针和闭包的问题
- swift - 使用 SwiftUI 自定义操作表
- python - 支持向量机的数学模型
- python - 如何为python中的短语而不是单个单词创建wordcloud
- javascript - 为什么 Javascript 中的这个 for 循环给我一个数字而不是从 0 到 4 的数字列表?
- wordpress - 基于用户角色的 Woocommerce 新客户电子邮件
- javascript - (NodeJS)可以维护客户端索引变量以使用 EJS 遍历数据库元素吗?