类中 dll 的回调函数
Posted
技术标签:
【中文标题】类中 dll 的回调函数【英文标题】:Callback function from a dll within a class 【发布时间】:2021-04-30 11:51:13 【问题描述】:我编写了一个 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 错误] Main.cpp(11422): E2034 将 'void (__stdcall * (_closure )(unsigned char *,unsigned long *))(unsigned char *,unsigned long *)' 转换为 'void (__stdcall *)( unsigned char *,unsigned long *)' 不可能。
我不知道如何处理那个 __closure 声明。我也试过 valr(&this->ReadHSCallBack) 这也无济于事。
【问题讨论】:
您可以使用非静态成员函数作为回调,因为 (a) 它们不是简单的函数指针,并且 (b) 它们需要调用对象。 【参考方案1】:不使用函数指针,可以使用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。
【讨论】:
嗨 Joseph,不幸的是,我使用的 IDE 不是现代的……它甚至不支持 std::function。根据这个***.com/a/7132549/9368347,它使用pre c++98 标准。它是 Embarcadero C++Builder 10.1。不幸的是我没有额外的更新,新版本已经使用了c++17。我想摆脱 c++builder 很长时间了,以至于我犹豫是否要购买进一步的更新。有什么“经典”的方法吗? 首先,这与您的 IDE 支持什么无关。你的编译器支持什么?话虽如此,您是否有某些原因与古老的开发环境联系在一起?您是否正在为一个非常古老的平台编码?如果是这样,那我不知道该告诉你什么。我早就换了 IDE。以上是关于类中 dll 的回调函数的主要内容,如果未能解决你的问题,请参考以下文章