使用私有成员函数调用Win32 QueueUserWorkItem()
我尝试使用Win32函数QueueUserWorkItem()
作为工作项来调用私有成员函数(不应该作为公共或受保护的方式提供)。我知道我以前做过这件事,而且很容易,但是现在我找不到那个片段,也不能让bind()
伏都教工作。因此,对于这个问题的目的,类是:使用私有成员函数调用Win32 QueueUserWorkItem()
class Arbitrary {
public:
Arbitrary() ;
~Arbitrary() ;
bool UsefulPublicFunction(unsigned uParameter) ;
protected:
private:
void PrivateWorkItem(void* pVoid) ;
} ;
而且里面UsefulPublicFunction()
我们可能会看到:
LPTHREAD_START_ROUTINE pThreadStartRoutine ;
ULONG uFlags = 0 ;
void* pContext = nullptr ;
if (QueueUserWorkItem(pThreadStartRoutine, pContext, uFlags)) {
//blah blah blah
}
在哪里我好像在杂草熄灭是分配给pThreadStartRoutine
喜欢的东西:
pThreadStartRoutine = std::bind<&Arbitrary::PrivateWorkItem, this, std::placeholders::_1> ;
我认识到,PrivateWorkItem
签名或许应该改为:
private:
DWORD WINAPI PrivateWorkItem(void* pVoid) ;
即使有了这样的变化,也没有快乐。 VS2015真的很讨厌我使用bind()
的方式。
我应该为pThreadStartRoutine
分配什么样的内容?
这似乎工作:
#include <Windows.h>
#include <stdio.h>
#include <functional>
using namespace std::placeholders;
class Arbitrary {
public:
bool UsefulPublicFunction(int uParameter);
protected:
private:
typedef std::function<void (void)> CallbackType;
static DWORD WINAPI ProcessWorkItem(void* pVoid);
void PrivateWorkItem1(int arg1, int arg2);
void PrivateWorkItem2(char * arg1);
};
void Arbitrary::PrivateWorkItem1(int arg1, int arg2)
{
printf("Numbers are %u %u\n", arg1, arg2);
return;
}
void Arbitrary::PrivateWorkItem2(char * arg1)
{
printf("String is %s\n", arg1);
return;
}
DWORD WINAPI Arbitrary::ProcessWorkItem(void* pVoid)
{
CallbackType * callback = static_cast<CallbackType *>(pVoid);
(*callback)();
delete callback;
return 0;
}
bool Arbitrary::UsefulPublicFunction(int param1)
{
QueueUserWorkItem(&ProcessWorkItem, new CallbackType(std::bind(&Arbitrary::PrivateWorkItem1, this, param1, 7)), 0);
QueueUserWorkItem(&ProcessWorkItem, new CallbackType(std::bind(&Arbitrary::PrivateWorkItem2, this, (char *)"This is my string")), 0);
Sleep(1000);
return true;
}
int main(int argc, char ** argv)
{
Arbitrary x;
x.UsefulPublicFunction(5);
return 0;
}
太棒了!谢谢。 – BenWestbrook
对不起,我还没有足够的分数来冲击哈利的“得分”。 – BenWestbrook
尝试一些更喜欢这个:
class Arbitrary {
public:
Arbitrary() ;
~Arbitrary() ;
bool UsefulPublicFunction(unsigned uParameter);
protected:
private:
static DWORD WINAPI PrivateWorkItem(void* pVoid) ;
void PrivateFunction();
} ;
DWORD WINAPI Arbitrary::PrivateWorkItem(void* pVoid)
{
static_cast<Arbitrary*>(pVoid)->PrivateFunction();
return 0;
}
...
if (QueueUserWorkItem(&PrivateWorkItem, this, 0)) {
//blah blah blah
}
这“感觉”相当笨拙,并且从长远的代码维护角度来看,我似乎没有那么可靠 - 主要是因为班上实际存在许多独特的私人工作者职能。但是,是的,我按照你的建议来完成它,而且我还用正确的签名声明和自动变量,然后用memcpy将它猛击到pThreadStartRoutine中,但对我来说这看起来很笨拙。 关于这一点,使用绑定似乎直截了当,当实习生在10年内维护此代码时的意图。 – BenWestbrook
您无法真正使用'std :: bind()'来设置Win32 API回调函数(请参阅http://stackoverflow.com/questions/18161680/)。我上面展示的是“最干净”的解决方案,不涉及丑陋的黑客。 –
你大概会使用一个静态函数,它接受一个指向由std :: bind生成的转发调用包装的指针。只要调用封装来自C++而不是Windows。 –
这将有助于了解你所看到的错误。 –
错误消息被请求...对我来说这是没用的 - 也许它对你有意义: “没有重载函数的实例”std :: bind“匹配所需的类型” – BenWestbrook