项目研发过程中用到了进程通信,由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 mmap
def IPC_CmdControl(IPC_Cmd,strScriptKeyWord,strParameter):
print(windll.kernel32.GetLastError())
buff_size = 1024
EVENT_ALL_ACCESS = 0x000F0000|0x00100000|0x3
shm = mmap.mmap(0, buff_size, "shared_memory")
OpenEvent=windll.kernel32.OpenEventW
m_hEvent = OpenEvent(2, True, "Global\\ShareMemoryEvent")
WaitEvent = OpenEvent(EVENT_ALL_ACCESS, True, "Global\\WaitResaultEvent")
strParameter = "\""+strParameter+"\"";
if shm:
shm[:] = b' ' * buff_size
shm.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)