使用CreateEvent()和OpenEvent()时长度为4n-1的命名事件异常
命名事件OpenEvent失败问题:名称长度为4n-1时返回NULL
我有两个应用程序,一个用CreateEvent()创建命名事件,另一个用OpenEvent()打开同一事件。应用A能成功创建事件,但应用B无法打开,返回句柄为NULL。测试发现当事件名称长度为4n-1时,OpenEvent()始终返回NULL,其他长度则正常工作。
应用A.exe代码
DLSRemoteConnnectionRqstEvent = CreateEvent(NULL, FALSE, FALSE, (LPCWSTR)DLS_REMOTE_CONNECTION_RQST_EVENT); if (GetLastError() != 0) { DLSRemoteConnnectionRqstEvent = OpenEvent(EVENT_ALL_ACCESS, TRUE,(LPCWSTR)DLS_REMOTE_CONNECTION_RQST_EVENT); } else { cout<<"DLS_REMOTE_CONNECTION_RQST_EVENT created"<<endl; }
应用B.exe代码
DLSRemoteConnnectionRqstEvent = OpenEvent(EVENT_ALL_ACCESS, TRUE, (LPCWSTR)DLS_REMOTE_CONNECTION_RQST_EVENT); if (GetLastError() != 0 && INVALID_HANDLE_VALUE == m_DLSRemoteConnnectionRqstEvent) { DLSRemoteConnnectionRqstEvent = CreateEvent(NULL, FALSE, FALSE, (LPCWSTR)DLS_REMOTE_CONNECTION_RQST_EVENT); } else { cout<<"m_DLSRemoteConnnectionRqstEvent opened"<<endl; }
公共头文件定义
#define CS_REMOTE_CONNECTION_RQST_EVENT "DLS_REMOTE_CONNECTION_RQST_MSG_TYPE"
问题根源:宽字符串转换的未终止异常
核心问题出在**ANSI字符串强制转换为宽字符指针(LPCWSTR)**的操作上:
- Windows API的
CreateEventW/OpenEventW(宽字符版本)要求传入的是以\0(双字节)结尾的宽字符串。 - 当你用
(LPCWSTR)把ANSI字符串(单字节)强制转换时,系统会将连续的单字节按宽字符(2字节/字符)解析。如果原ANSI字符串的字符数(不含终止符)是4n-1,那么总字节数为(4n-1)+1=4n,刚好是2n个宽字符的字节数——此时原ANSI的单字节\0会被当成某个宽字符的低字节,而高字节是内存中的随机值,导致宽字符串没有正确的双字节终止符。 - 这种情况下,
OpenEvent会使用错误的事件名称(超出预期长度的乱码名称),自然找不到已创建的事件,返回NULL。而当名称长度不符合4n-1时,单字节终止符刚好能被解析为有效的宽字符终止符,所以能正常工作。
解决方法
统一使用宽字符串定义事件名称
直接将宏定义改为宽字符串,避免强制转换:#define CS_REMOTE_CONNECTION_RQST_EVENT L"DLS_REMOTE_CONNECTION_RQST_MSG_TYPE"正确转换ANSI到宽字符
如果必须使用ANSI字符串,用MultiByteToWideChar函数完成转换,而非强制类型转换:wchar_t eventName[256]; MultiByteToWideChar(CP_ACP, 0, CS_REMOTE_CONNECTION_RQST_EVENT, -1, eventName, 256); DLSRemoteConnnectionRqstEvent = CreateEvent(NULL, FALSE, FALSE, eventName);精准排查错误码
调用OpenEvent后,通过GetLastError()获取具体错误码(如ERROR_FILE_NOT_FOUND、ERROR_ACCESS_DENIED),能更精准定位问题,不要只判断句柄是否为NULL。
内容的提问来源于stack exchange,提问作者ashish patil
相关产品推荐
相关产品推荐

