我已经编写了一个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*("(unsignedchar*,signed 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.");
到目前为止,这是cut&粘贴我目前正在处理的程序中的实际代码。lambda可以做任何事情,所以我可以这样做:
vec.addArg("port", [=](const char *arg){ foo(arg); });
请注意,我使用了=而不是&。
你可以做整个std::bind((的事情,但我觉得很难看,宁愿传递一个lambda。
使用C风格的函数指针非常像C,C++程序员应该使用现代方法。这意味着std::函数,可能还有lambdas。