bounty将在2小时后过期。回答此问题可获得+50声望奖励。IOviSpot希望引起更多人关注此问题。
我正在尝试让两个DLL互相通信。一个用作管道服务器,只要程序运行就保持活动状态,另一个用作管道客户端,在管道服务器处于活动状态时,可以在给定的情况下连接和断开连接。请考虑以下函数:
DLL1(管道服务器)
void DLL1_Begin() // This gets called only once, when the program starts
{
g_hPipeServer = CreateNamedPipe(TEXT("\\\\.\\pipe\\MyPipe123"),
PIPE_ACCESS_DUPLEX,
PIPE_TYPE_BYTE | PIPE_READMODE_BYTE | PIPE_NOWAIT,
1,
4,
4,
NMPWAIT_USE_DEFAULT_WAIT,
NULL);
if (g_hPipeServer == INVALID_HANDLE_VALUE)
{
char error[256];
sprintf_s(error, "Server pipe error %lu", GetLastError());
MessageBox(NULL, error, "Fatal error", MB_OK | MB_ICONERROR);
exit(1);
}
ConnectNamedPipe(g_hPipeServer, NULL);
}
void DLL1_End() // This gets called only once, when the program closes
{
DisconnectNamedPipe(g_hPipeServer);
CloseHandle(g_hPipeServer);
}
DLL2(管道客户端)
// Like DLL1, DLL2 gets initialized once and is always attached to the program.
// These functions are called occasionally and are meant solely for the Pipe.
void DLL2_InitPipeClient()
{
g_hClientPipe = CreateFile(TEXT("\\\\.\\pipe\\MyPipe123"),
GENERIC_READ | GENERIC_WRITE,
0,
NULL,
OPEN_EXISTING,
0,
NULL);
if (g_hClientPipe == INVALID_HANDLE_VALUE) // This scope is of interest
{
char error[256];
sprintf_s(error, "Client pipe error %lu", GetLastError());
MessageBox(NULL, error, "Fatal error", MB_OK | MB_ICONERROR);
exit(1);
}
}
void DLL2_EndPipeClient()
{
CloseHandle(g_hClientPipe);
g_hClientPipe = NULL;
}
具体步骤如下:
1.程序启动,连接DLL1
并调用DLL1_Begin
1.在任何时候,用户与按钮交互,DLL2
被连接,DLL2_InitPipeClient
被调用。只要程序在运行,DLL2
就保持连接到程序
1.在任何时候,用户与另一个按钮交互,调用DLL2_EndPipeClient
,然后立即调用DLL2_InitPipeClient
。
1.客户端管道第二次无法使用CreateFile
初始化,给出error 231
用户需要能够随时“重新启动”客户端管道。为什么服务器管道会忙碌呢?CloseHandle总是返回true,但在此之后,调用CreateFile
将返回INVALID_HANDLE_VALUE
和error 231
。
请注意,我一次只能有一个管道客户端。我尝试将CreateNamedPipe
的maxinstances参数设置为一个更高的值以防万一,但错误没有消失,我无法初始化客户端管道...我该如何解决这个问题?
顺便说一下,通信是来回的,我只是不能让Client管道关闭并重新启动,而且我不能让它一直处于活动状态,这超出了我的能力范围。
1条答案
按热度按时间uxhixvfz1#
根据[MS.文件]:ConnectNamedPipe函数(namedpipeapi. h)-备注(强调的是我的):
命名管道服务器进程可以将ConnectNamedPipe与新创建的管道示例一起使用。***它还可以与以前连接到另一个客户端进程的示例一起使用;在这种情况下,服务器进程必须首先调用DisconnectNamedPipe函数,以便在句柄可以重新连接到新客户端之前断开句柄与先前客户端的连接。否则,ConnectNamedPipe返回零,并且如果先前客户端已经关闭其句柄,则GetLastError返回ERROR_NO_DATA,或者如果先前客户端尚未关闭其句柄,则GetLastError返回ERROR_PIPE_CONNECTED。
我修改了你的消息来源,让你有了一个可行的例子。
备注:
输出:
在上面的输出中,可以看到 *ERROR_PIPE_忙碌 * 仅在客户端尝试连接两次(已经有一个连接的客户端)时发生。
有关更多详细信息,您可以查看: