项目研发过程中用到了进程通信,由C++应用程序创建共享内存及两个同步事件(Event1、Event2),然后阻塞等待外部进程激活事件Event1,Event1激活后,C++应用程序读取共享内存中的数据,完成数据解析后执行相应指令,并向共享内存中写入指令执行结果,同时激活事件Event2;而Python进程则负责打开共享内存和两个同步事件,向共享内存中写入数据,并激活Event1,然后阻塞等待Event2被激活,Event2激活后,读取共享内存中的数据。进程通讯关系如下图所示:
C++程序源码如下:
DWORD WINAPI IPC_ReadExecuteCmd(LPVOID lpParameter)
{unsigned long buff_size = IPC_BufferSize;ControlCmdPara ReceiveData;memset(&ReceiveData, 0, sizeof(ReceiveData));ControlCmdPara SendData;memset(&SendData, 0, sizeof(SendData));HANDLE file_shared_handler = CreateFile(L"shared_memory",GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);if (file_shared_handler == INVALID_HANDLE_VALUE)cout << "create file error" << endl;HANDLE file_mapping_handler = CreateFileMapping(file_shared_handler, NULL, PAGE_READWRITE, 0, buff_size, L"shared_memory");if (file_mapping_handler == INVALID_HANDLE_VALUE)cout << "create file_mapping error" << endl;LPVOID lp_base = MapViewOfFile(file_mapping_handler, FILE_MAP_ALL_ACCESS, 0, 0, 0);if (lp_base == INVALID_HANDLE_VALUE)cout << "MapViewOfFile error" << endl;HANDLE m_hEvent = CreateEvent(NULL, FALSE, FALSE, GLOBAL_EVENT_NAME);if (m_hEvent == nullptr)cout << "create Event error";HANDLE WaitEvent = CreateEvent(NULL, FALSE, FALSE, GLOBAL_EVENT_WAIT);if (WaitEvent == nullptr)cout << "create WaitEvent error";CString IPC_Cmd, strScriptKeyWord, strParameter;LRESULT lScriptCmdResult = 0;while (true){WaitForSingleObject(m_hEvent, INFINITE);memcpy(&ReceiveData, lp_base, buff_size);/* 调用API执行指令*/IPC_Cmd = string(ReceiveData.Cmd).substr(0, 15).c_str();strScriptKeyWord = string(ReceiveData.YjksCmd).substr(0, 31).c_str();strParameter = string(ReceiveData.Para).substr(0, 975).c_str();strScriptKeyWord.TrimRight();strParameter.TrimRight();IPC_Cmd.TrimRight();string ResaultStr = "Success";strcpy(SendData.Cmd, "Result");if (!IPC_Cmd.CompareNoCase(PLAYBACK)){lScriptCmdResult = IPC_ExecuteScrCmd(strScriptKeyWord, strParameter);}if (!IPC_Cmd.Compare(RECORD)){lScriptCmdResult = IPC_ExecuteScrCmd(L"_makescript", L"");}if (lScriptCmdResult < 0) ResaultStr = "Failure";strcpy(SendData.Para, ResaultStr.c_str());memcpy(lp_base, &SendData, buff_size);if (WaitEvent != nullptr) SetEvent(WaitEvent);}FlushViewOfFile(lp_base, buff_size);UnmapViewOfFile(lp_base);CloseHandle(file_mapping_handler);CloseHandle(file_shared_handler);return 0;
}
Python程序源码如下:
from ctypes import *
import mmapdef IPC_CmdControl(IPC_Cmd,strScriptKeyWord,strParameter):print(windll.kernel32.GetLastError())buff_size = 1024EVENT_ALL_ACCESS = 0x000F0000|0x00100000|0x3shm = mmap.mmap(0, buff_size, "shared_memory")OpenEvent=windll.kernel32.OpenEventWm_hEvent = OpenEvent(2, True, "Global\\ShareMemoryEvent")WaitEvent = OpenEvent(EVENT_ALL_ACCESS, True, "Global\\WaitResaultEvent")strParameter = "\""+strParameter+"\"";if shm:shm[:] = b' ' * buff_sizeshm.seek(0)shm.write(bytes(IPC_Cmd, 'UTF-8'))shm.seek(16)shm.write(bytes(strScriptKeyWord, 'UTF-8'))shm.seek(48)shm.write(bytes(strParameter, 'UTF-8'))windll.kernel32.SetEvent(m_hEvent)windll.kernel32.WaitForSingleObject(WaitEvent,-1)shm.seek(48)return shm.read(7).rstrip()if __name__ == '__main__':IPC_CmdControl(IPC_Cmd,strScriptKeyWord,strParameter)