我创建了这个帐户来提问,因为我现在很迷茫而且找不到答案。我不确定我想做的事情是否可行,或者我采取的方法不正确。
我正在为异步套接字编写一个Windows套接字包装类,大部分时间我都不必再次编写这个代码了,我试图将一个函数指针存储为我的netcode类中指向一个窗口的成员变量在应用程序的正常win32消息泵内部调用的事件处理程序指向其他位置。基本上,我正在尝试创建一个程序员定义的回调函数,这样当我将这个netcode类编译成.dll时,我再也不用再触摸它了。
作为澄清,我正在尝试做的是,例如,在网络代码类之外的某个地方编写WM_SOCKET
的事件处理程序(这是我定义的一个Windows消息)(所以它可以移植到不同的win32 / C ++项目)和主win32消息泵之外(所以我的WndProc()
不会变得非常庞大)。
我甚至不知道要搜索什么,但我找到的所有信息都是关于创建指向成员函数或模板成员的指针,这不是我想要的。
这是我已经尝试编写的代码(只有相关位),这就是给我带来问题的原因。我可能在这里搞错了。
//// Sockets.h
class NetworkConnection
{
private:
void (*WMSocketFunction)(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam);
public:
void HandleEvents(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam);
void registerSocketFunction( void (*SocketFunction(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)));
};
//// Sockets.cpp
#include "Sockets.h"
void NetworkConnection::registerSocketFunction( void (*SocketFunction(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)))
{
WMSocketFunction = SocketFunction;
};
void NetworkConnection::HandleEvents(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
WMSocketFunction(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam);
}
//// Application.cpp
void SocketEventHandler(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
// Do socket stuff here
};
int SetupApp()
{
NetworkConnection NetConnection;
NetConnection.registerSocketFunction(&SocketEventHandler);
return 0;
}
LRESULT CALLBACK d3d::WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
switch( msg )
{
case WM_SOCKET:
{
NetConnection.HandleEvents(hwnd, msg, wParam, lParam);
break;
}
case WM_DESTROY:
{
ReleaseDevices();
break;
}
case WM_KEYDOWN:
{
#ifdef _DEBUG
if (lParam == VK_ESCAPE)
PostQuitMessage(0);
#endif
}
}
return ::DefWindowProc(hwnd, msg, wParam, lParam);
}
我非常感谢你的帮助。我完全不知道为什么这不起作用。
我收到的错误是:
Error 1 error C2440: '=' : cannot convert from 'void *(__cdecl *)(HWND,UINT,WPARAM,LPARAM)' to 'void (__cdecl *)(HWND,UINT,WPARAM,LPARAM)' sockets.cpp (in function registerSocketFunction)
Error 2 error C2275: 'HWND' : illegal use of this type as an expression sockets.cpp (in function HandleEvents)
Error 3 error C2146: syntax error : missing ')' before identifier 'hwnd' sockets.cpp (in function HandleEvents)
Error 4 error C2059: syntax error : ')' sockets.cpp (in function HandleEvents)
Error 8 error C2664: 'NetworkConnection::registerSocketFunction' : cannot convert parameter 1 from 'void (__cdecl *)(HWND,UINT,WPARAM,LPARAM)' to 'void *(__cdecl *)(HWND,UINT,WPARAM,LPARAM)' application.cpp
如果您需要更好的解释,因为我可能很难解释这个问题,请不要犹豫。
我正在使用Visual Studio 2010,所以我认为我不能使用像std :: function这样的C ++ / 11功能。
答案 0 :(得分:4)
使用typedef使代码更清晰
typedef void(*WMSocketFunction_Ptr)(HWND, UINT, WPARAM, LPARAM);
class NetworkConnection
{
private:
WMSocketFunction_Ptr WMSocketFunction;
public:
void HandleEvents(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam);
void registerSocketFunction(WMSocketFunction_Ptr SocketFunction);
};
void NetworkConnection::registerSocketFunction(WMSocketFunction_Ptr SocketFunction)
{
WMSocketFunction = SocketFunction;
};
更喜欢将STL设施用于裸指针:std::function boost::function
typedef std::function<void(HWND, UINT, WPARAM, LPARAM)> WMSocketFunction_Ptr;
答案 1 :(得分:2)
您必须将函数指针名称括在括号中,如下所示:void (*SocketFunction)(...)
所以不是你的方法声明:
void registerSocketFunction( void (*SocketFunction(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)));
你必须写:
void registerSocketFunction( void (*SocketFunction)(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam));
还要将您的方法体重写为:
void NetworkConnection::registerSocketFunction( void (*SocketFunction)(HWND, UINT, WPARAM, LPARAM))
{
WMSocketFunction = SocketFunction;
};
接下来,我认为你的HandleEvents尚未完成,你有一个语法错误,我想你想调用指针后面的函数。
void NetworkConnection::HandleEvents(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
WMSocketFunction(hwnd,msg,wParam,lParam);
}
答案 2 :(得分:1)
这是我的怀疑。我认为您为SocketFunction
声明函数参数registerSocketFunction
的方式是错误的。
void NetworkConnection::registerSocketFunction( void (*SocketFunction(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)))
应该是,
void NetworkConnection::registerSocketFunction( void (*SocketFunction)(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam))
我在GCC上运行了类似的测试,它也发出了类似的错误,所以这可能是你的问题。