win32相关(进程间通信)
进程间通信
每个进程都有自己独立的4GB内存空间(虚拟的),彼此间不能互相访问的。如果需要进程通信则需要使用一些方法
WM_COPYDATA的方式发送消息
WM_COPYDATA是一个特殊的专门用于传递数据的消息,这个消息可以携带一个大体积的消息参数
在发送WM_COPYDATA 消息时,Wparam应该保存有发送此消息的窗口句柄,Lparam则应该指向一个名为COPYDATASTRUCT的结构体
// COPYDATASTRUCT结构体信息
typedef struct tagCOPYDATASTRUCT {ULONG_PTR dwData;DWORD cbData;_Field_size_bytes_(cbData) PVOID lpData;
} COPYDATASTRUCT, *PCOPYDATASTRUCT;
消息接收端
#include<windows.h>
#include"resource.h"INT_PTR CALLBACK WinProc(HWND hwnd,UINT msg,WPARAM wParam,LPARAM lParam)
{switch (msg) {case WM_COPYDATA: //接收WM_COPYDATA类型的消息{// lParam里面存储着WM_COPYDATA消息发送的COPYDATASTRUCT结构体数据PCOPYDATASTRUCT pcds = (PCOPYDATASTRUCT)lParam; MessageBox(hwnd, (LPCWSTR)pcds->lpData, TEXT("接收"), MB_OK);break;}case WM_CLOSE:{EndDialog(hwnd, 0);break;}default:return FALSE;}return TRUE;
}
// 窗口程序
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
{DialogBox(hInstance, MAKEINTRESOURCE(IDD_DIALOG1), NULL, WinProc);return 0;
}
消息发送端
#include<windows.h>int main() {// 获取窗口句柄HWND hWnd = FindWindow(NULL, L"51HOOK");// 创建要发送消息的COPYDATASTRUCT结构体对象COPYDATASTRUCT cds;// 要发送的数据cds.lpData = (LPVOID)L"hello world";// 发送数据的长度cds.cbData = (wcslen((LPCWSTR)cds.lpData) + 1) * sizeof(wchar_t); // 包括终止符// 发送消息SendMessage(hWnd, WM_COPYDATA, 0, (LPARAM)&cds);system("pause");return 0;
}
以邮槽的方式发送消息
- 以邮槽的方式发送消息是windows中最简单的一种进程间的通信方式,一个进程可以创建一个邮槽,其他进程则可以通过打开此邮槽与该进程通信
- 邮槽的通讯是单向的,只有服务端才能从邮槽中读取消息,客户端只能写入,消息被写入以队列的方式保存(先进先出)
- 邮槽除了可以在本机进行通讯外,还可能在主机之前进行通讯(使用UDP协议)
邮槽常用函数
CreateMailslot 创建邮槽
GetMailSlotInfo 获取邮槽信息
CreateFile 打开文件
WriteFile 写入文件
ReadFile 读取文件
邮槽发送端
#include<windows.h>// 发送端
int main() {HANDLE hMailslot = CreateFile(L"\\\\.\\mailslot\\SendMsg", GENERIC_WRITE, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);if (hMailslot == INVALID_HANDLE_VALUE) {MessageBox(NULL, L"打开邮槽失败", L"错误", MB_OK);return -1;}WCHAR buf[] = L"hello world";DWORD sz;WriteFile(hMailslot, buf, (wcslen(buf) * sizeof(WCHAR)),&sz,NULL);CloseHandle(hMailslot);return 0;
}
邮槽接收端
#include<windows.h>// 接收端
int main()
{HANDLE hMailslot = CreateMailslot(L"\\\\.\\mailslot\\SendMsg", 100, MAILSLOT_WAIT_FOREVER, NULL);if (hMailslot == INVALID_HANDLE_VALUE) {MessageBox(NULL, L"创建邮槽失败", L"错误", MB_OK);return -1;}WCHAR buf[100] = { 0 };DWORD readSize;ReadFile(hMailslot, buf, 100, &readSize, NULL);MessageBox(NULL,buf,L"接收",MB_OK);CloseHandle(hMailslot);return 0;
}