|
|
VC++进程间消息通信方案:WM_COPYDATA 与命名管道(Named Pipe)
下面给出两种常用进程间消息通信方案的最小示例:WM_COPYDATA 与命名管道(Named Pipe)。 WM_COPYDATA(同机窗口间发送小块文本/数据) 发送端 - #define WIN32_LEAN_AND_MEAN
- #include <windows.h>
- #include <string>
- void SendIpc(HWND hTarget, const std::string& text) {
- COPYDATASTRUCT cds{};
- cds.dwData = 1; // 自定义标识
- cds.cbData = static_cast<DWORD>(text.size() + 1);
- cds.lpData = (PVOID)text.c_str(); // 包含 NUL 结尾
- SendMessage(hTarget, WM_COPYDATA, (WPARAM)nullptr, (LPARAM)&cds);
- }
- // 示例:找到对方窗口并发送
- int main() {
- HWND hTarget = FindWindowW(L"MyWndClass", nullptr); // 对方窗口类名
- if (hTarget) SendIpc(hTarget, "Hello from WM_COPYDATA");
- return 0;
- }
复制代码 接收端(窗口过程)- #define WIN32_LEAN_AND_MEAN
- #include <windows.h>
- #include <string>
- LRESULT CALLBACK WndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam) {
- switch (msg) {
- case WM_COPYDATA: {
- auto pcds = reinterpret_cast<PCOPYDATASTRUCT>(lParam);
- if (pcds && pcds->lpData && pcds->cbData > 0) {
- const char* s = static_cast<const char*>(pcds->lpData);
- OutputDebugStringA(s); // 处理消息
- }
- return TRUE;
- }
- // ...其他分支...
- }
- return DefWindowProc(hWnd, msg, wParam, lParam);
- }
复制代码 Named Pipe(可双向收发,适合较大量数据) 管道服务端(阻塞式)
- #define WIN32_LEAN_AND_MEAN
- #include <windows.h>
- #include <cstdio>
- DWORD WINAPI PipeServerThread(LPVOID) {
- const wchar_t* pipename = L"\\\\.\\pipe\\MyPipe";
- for (;;) {
- HANDLE hPipe = CreateNamedPipeW(
- pipename,
- PIPE_ACCESS_DUPLEX,
- PIPE_TYPE_BYTE | PIPE_READMODE_BYTE | PIPE_WAIT,
- PIPE_UNLIMITED_INSTANCES,
- 4096, 4096, 0, nullptr);
- if (hPipe == INVALID_HANDLE_VALUE) { break; }
- BOOL ok = ConnectNamedPipe(hPipe, nullptr) ? TRUE :
- (GetLastError() == ERROR_PIPE_CONNECTED);
- if (!ok) { CloseHandle(hPipe); continue; }
- char buf[1024];
- DWORD n = 0;
- if (ReadFile(hPipe, buf, sizeof(buf) - 1, &n, nullptr)) {
- buf[n] = 0;
- printf("Server recv: %s\n", buf);
- const char reply[] = "ACK";
- DWORD wn = 0;
- WriteFile(hPipe, reply, sizeof(reply) - 1, &wn, nullptr);
- }
- FlushFileBuffers(hPipe);
- DisconnectNamedPipe(hPipe);
- CloseHandle(hPipe);
- }
- return 0;
- }
- int main() {
- CreateThread(nullptr, 0, PipeServerThread, nullptr, 0, nullptr);
- Sleep(INFINITE);
- return 0;
- }
复制代码
管道客户端
- #define WIN32_LEAN_AND_MEAN
- #include <windows.h>
- #include <cstdio>
- int main() {
- const wchar_t* pipename = L"\\\\.\\pipe\\MyPipe";
- // 等待服务端创建好
- if (!WaitNamedPipeW(pipename, 5000)) return 1;
- HANDLE h = CreateFileW(pipename, GENERIC_READ | GENERIC_WRITE, 0, nullptr,
- OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, nullptr);
- if (h == INVALID_HANDLE_VALUE) return 2;
- const char msg[] = "Hello Pipe";
- DWORD wn = 0;
- WriteFile(h, msg, sizeof(msg) - 1, &wn, nullptr);
- char buf[1024];
- DWORD rn = 0;
- if (ReadFile(h, buf, sizeof(buf) - 1, &rn, nullptr)) {
- buf[rn] = 0;
- printf("Client recv: %s\n", buf);
- }
- CloseHandle(h);
- return 0;
- }
复制代码
提示 - WM_COPYDATA 适合小数据、同机窗口;命名管道适合任意进程、双向通信。
- 生产中建议为管道加超时、协议帧头、长度校验与线程化处理。
|
|