工作中碰到了32位dll和64位dll通信问题,上网搜索了相关的问题,发现最简单的实现方式就是利用WM_COPYDATA消息传递,很多博客给出了实现代码,但大部分都是发送端C++,接收端C#或MFC。本文给出自己实现的简单例子,发送接收相互通信,都是用C++实现。
目录
WM_COPYDATA 消息
代码实现
An application sends the WM_COPYDATA message to pass data to another application.即一个程序通过WM_COPYDATA消息传递数据给另一个程序。
该消息只能由 SendMessage()
发送 ,SendMessage()需要知道进程句柄,所以
一般都搭配FindWindow()使用。通过FindWindow查找进程句柄,然后使用SendMessage() 向这个句柄发送信息
进程A:
#include"windows.h"
#include"stdlib.h"
#include"stdio.h"
#include"tchar.h"
#include
#include
HWND gHandB;
HWND gHandA;
int sendInit();
void sendMsg(int code, int len = 0, void* data = NULL);
LRESULT CALLBACK WindowProc(
_In_ HWND hwnd,
_In_ UINT message,
_In_ WPARAM wParam,
_In_ LPARAM lParam
){
if (message == WM_COPYDATA){
COPYDATASTRUCT *pCopyData = (COPYDATASTRUCT*)lParam;
printf("Process A Rec:code = %x,msg = %s\n", pCopyData->dwData, pCopyData->lpData);
}
return DefWindowProc(hwnd, message, wParam, lParam);
}
void msgThread(void* reserved){
WNDCLASS wndClass;
HINSTANCE hCurrentInst = GetModuleHandle(NULL);
ZeroMemory(&wndClass, sizeof(WNDCLASS));
wndClass.style = CS_OWNDC | CS_HREDRAW | CS_VREDRAW;
wndClass.lpfnWndProc = WindowProc;
wndClass.cbClsExtra = 0;
wndClass.cbWndExtra = 0;
wndClass.hInstance = hCurrentInst;
wndClass.hIcon = LoadIcon(NULL, IDI_APPLICATION);
wndClass.hCursor = LoadCursor(NULL, IDC_ARROW);
wndClass.hbrBackground = (HBRUSH)GetStockObject(BLACK_BRUSH);
wndClass.lpszMenuName = NULL;
wndClass.lpszClassName = TEXT("ProcessA");
RegisterClass(&wndClass);
gHandA = CreateWindow(TEXT("ProcessA"), TEXT("ProcessA"),
WS_OVERLAPPEDWINDOW | WS_CAPTION | WS_CLIPCHILDREN,
1, 1,
320, 240,
0, 0, hCurrentInst, 0);
ShowWindow(gHandA, SW_HIDE);
UpdateWindow(gHandA);
MSG msg;
while (GetMessage(&msg, NULL, 0, 0) == TRUE) {
TranslateMessage(&msg);
DispatchMessage(&msg);
}
}
int sendInit(){
int ret = 0;
gHandB = FindWindow(NULL, _T("ProcessB"));
if (gHandB == NULL)
ret = -1;
return ret;
}
void sendMsg(int code, int len, void* data){
COPYDATASTRUCT CopyData;
CopyData.dwData = code;//保存一个数值, 可以用来作标志等
CopyData.cbData = len;// strlen(szSendBuf);//待发送的数据的长度
CopyData.lpData = data;// szSendBuf;//待发送的数据的起始地址(可以为NULL)
SendMessage(gHandB, WM_COPYDATA, (WPARAM)gHandB, (LPARAM)&CopyData);
}
int main(int argc, char* argv[]){
printf("This is 进程A\n ");
/**********************************************************************************/
if (argc != 2)
return -1;
std::string svacExePath = argv[1];
int ret = WinExec(svacExePath.c_str(), SW_SHOWMAXIMIZED);
Sleep(100);
if (ret > 31)
printf("Execute SvacClient Success\n");
std::thread msgThread(msgThread, (void*)NULL);
msgThread.detach();
//wait process B
while (sendInit() != 0)
Sleep(1);
//send msg
char _buf[] = "Msg from process A.";
sendMsg(0x01, sizeof(_buf), _buf);
//printf("Send initial success\n ");
//close processB
std::string killExe = "taskkill /f /t /im ";
killExe += svacExePath;
WinExec(killExe.c_str(), SW_HIDE);
return 0;
}
进程B:
#include
#include
#include
#include
HWND gHandB;
HWND gHandA;
void sendMsg(int code, int len = 0, void* data = NULL);
int sendInit();
LRESULT CALLBACK WindowProc(
_In_ HWND hwnd,
_In_ UINT message,
_In_ WPARAM wParam,
_In_ LPARAM lParam
){
if (message == WM_COPYDATA){
COPYDATASTRUCT *pCopyData = (COPYDATASTRUCT*)lParam;
printf("Process B Rec:code = %x,msg = %s\n", pCopyData->dwData, pCopyData->lpData);
while (sendInit() != 0)
Sleep(1);
char _buf[] = "Msg from process B.";
sendMsg(0x02, sizeof(_buf), _buf);
}
return DefWindowProc(hwnd, message, wParam, lParam);
}
void msgTreadFun(void* reserved){
WNDCLASS wndClass;
HINSTANCE hCurrentInst = GetModuleHandle(NULL);
ZeroMemory(&wndClass, sizeof(WNDCLASS));
wndClass.style = CS_OWNDC | CS_HREDRAW | CS_VREDRAW;
wndClass.lpfnWndProc = WindowProc;
wndClass.cbClsExtra = 0;
wndClass.cbWndExtra = 0;
wndClass.hInstance = hCurrentInst;
wndClass.hIcon = LoadIcon(NULL, IDI_APPLICATION);
wndClass.hCursor = LoadCursor(NULL, IDC_ARROW);
wndClass.hbrBackground = (HBRUSH)GetStockObject(BLACK_BRUSH);
wndClass.lpszMenuName = NULL;
wndClass.lpszClassName = TEXT("ProcessB");
RegisterClass(&wndClass);
gHandB = CreateWindow(TEXT("ProcessB"), TEXT("ProcessB"),
WS_OVERLAPPEDWINDOW | WS_CAPTION | WS_CLIPCHILDREN,
1, 1,
320, 240,
0, 0, hCurrentInst, 0);
ShowWindow(gHandB, SW_HIDE);
UpdateWindow(gHandB);
MSG msg;
while (GetMessage(&msg, NULL, 0, 0) == TRUE) {
TranslateMessage(&msg);
DispatchMessage(&msg);
}
}
int sendInit(){
int ret = 0;
const char szDlgTitle[] = "ProcessA";
gHandA = FindWindow(NULL, szDlgTitle);
if (gHandA == NULL)
ret = -1;
return ret;
}
void sendMsg(int code, int len, void* data){
COPYDATASTRUCT CopyData;
CopyData.dwData = code;//保存一个数值, 可以用来作标志等
CopyData.cbData = len;// strlen(szSendBuf);//待发送的数据的长度
CopyData.lpData = data;// szSendBuf;//待发送的数据的起始地址(可以为NULL)
SendMessage(gHandA, WM_COPYDATA, (WPARAM)gHandB, (LPARAM)&CopyData);
}
int main(int argc, char* argv[]){
printf("This is 进程B\n ");
/**********************************************************************************/
int ret = 0;
int time = 0;
//Rec Thread
std::thread msgThread(msgTreadFun, (void*)NULL);
msgThread.detach();
while (gHandB == NULL)
Sleep(1);
while (1){
Sleep(1);
}
return 0;
}
运行: