首页 > 解决方案 > 类中 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) 也没有帮助。

标签: c++callbackfunction-pointersmember-function-pointers

解决方案


除了使用函数指针,你可以使用 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。


推荐阅读