使用 CreateEvent() 和 Openevent() 的长度为 4*n-1 的命名事件出现问题

Problem with Named event of length 4*n-1using CreateEvent() and Openevent()

提问人:ashish patil 提问时间:11/11/2022 最后编辑:Remy Lebeauashish patil 更新时间:11/11/2022 访问量:46

问:

我有两个应用程序,一个使用 创建一个命名事件,另一个使用 打开相同的事件,如下所示:CreateEvent()OpenEvent()

应用程序 .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"

应用程序 A 能够成功创建事件,但应用程序 B 无法打开该事件,从而获得 NULL 的句柄值。

我已经测试了几种场景,并知道如果事件名称的长度为 4 n-1,那么打开的事件总是给我一个 NULL 句柄值,如果事件名称小于4 n-1 或大于 4*n-1,那么我的应用程序工作正常。

请帮助说明为什么我的应用程序在事件名称长度为 4*n-1 时会表现得如此。

与上述类似,在应用程序中创建和打开的其他事件工作正常,因为它们的长度不是 4*n-1。

CreateEvent()并且应该适用于所有事件长度。OpenEvent()

多线程 WinAPI 事件

评论

1赞 user3161924 11/11/2022
定义不应该是:#define CS_REMOTE_CONNECTION_RQST_EVENT _T("DLS_REMOTE_CONNECTION_RQST_MSG_TYPE")
0赞 Remy Lebeau 11/11/2022
@user3161924正确的,尽管从技术上讲,它应该使用 .TEXT()_T()

答:

0赞 Remy Lebeau 11/11/2022 #1

你的类型转换是错误的。你不能像现在这样把窄弦变成宽弦。首先使用宽字符串文字,例如:LPCWSTR

#define CS_REMOTE_CONNECTION_RQST_EVENT L"DLS_REMOTE_CONNECTION_RQST_MSG_TYPE"
...
CreateEventW(..., DLS_REMOTE_CONNECTION_RQST_EVENT);
...
OpenEventW(..., DLS_REMOTE_CONNECTION_RQST_EVENT);

话虽如此,使用和你的方式会导致竞争条件。由于很明显,如果事件尚不存在,则任一应用程序都可以创建事件,因此您应该在两个应用程序中使用,并让它为您避免争用条件。根本没有理由在此代码中使用。CreateEvent()OpenEvent()CreateEvent()OpenEvent()

此外,您的错误检查是错误的。应用程序 A 在查找失败错误代码之前不会检查是否确实发生了故障。 可以在成功和失败条件下报告非零错误代码。应用程序 B 至少尝试检查是否失败,但它这样做不正确,因为失败时返回,而不是 .CreateEvent()OpenEvent()OpenEvent()NULLINVALID_HANDLE_VALUE

请尝试以下操作:

应用程序 A.exe 和 B.exe:

#define CS_REMOTE_CONNECTION_RQST_EVENT L"DLS_REMOTE_CONNECTION_RQST_MSG_TYPE"
...
DLSRemoteConnnectionRqstEvent = CreateEventW(NULL, FALSE, FALSE, DLS_REMOTE_CONNECTION_RQST_EVENT);
if (NULL == DLSRemoteConnnectionRqstEvent)
{
    // error handling...
}
else
{
    if (GetLastError() == ERROR_ALREADY_EXISTS)
        cout << "DLS_REMOTE_CONNECTION_RQST_EVENT opened" << endl;
    else
        cout << "DLS_REMOTE_CONNECTION_RQST_EVENT created" << endl;
}

评论

0赞 ashish patil 11/14/2022
感谢您的指正。如果事件名称长度正好是 4*n-1,您能否让我知道应用程序 B 无法执行 openevent() 的具体原因。对于大于 4n-1 或小于 4n-1 的其他长度,它工作得很好。
0赞 Remy Lebeau 11/14/2022
@ashishpatil没有这样的长度限制。原始代码将无效字符串传递给函数,并错误地检查失败。我给你的代码应该在两个应用程序中都能正常工作。