QT(6.5) cmake构建C++编程,c++与python进行通信(命名管道)
- 首先,c++端编写命名管导通信代码
#include <QDebug>
#include <windows.h>
bool fifp_cpp(){
HANDLE hPipe;
hPipe = CreateNamedPipeW(
L"\\\\.\\pipe\\pretectPipe",
PIPE_ACCESS_DUPLEX,
PIPE_TYPE_MESSAGE | PIPE_READMODE_MESSAGE | PIPE_WAIT,
1,
0,
0,
0,
NULL);
if (hPipe == INVALID_HANDLE_VALUE) {
qDebug() << "CreateNamedPipe failed with error(INVALID_HANDLE_VALUE): " << GetLastError() << "\n";
return false;
}
qDebug() << "管道创建成功" << "\n";
if (ConnectNamedPipe(hPipe, NULL) == FALSE) {
if (GetLastError() != ERROR_PIPE_CONNECTED) {
qDebug() << "ConnectNamedPipe failed with error(超时): " << GetLastError() << "\n";
CloseHandle(hPipe);
return false;
}
}
qDebug() << "管道已被连接" << "\n";
std::string message_from_cpp = "1";
DWORD bytesWritten;
WriteFile(hPipe, message_from_cpp.c_str(), static_cast<DWORD>(message_from_cpp.length() + 1), &bytesWritten, NULL);
qDebug() << "发送开始信号" << "\n";
char buffer[1024];
DWORD bytesRead;
bool pipeStop = false;
int read_total = 0;
do {
if (PeekNamedPipe(hPipe, NULL, 0, NULL, &bytesRead, NULL)) {
if (bytesRead > 0) {
ReadFile(hPipe, buffer + read_total, sizeof(buffer) - read_total, &bytesRead, NULL);
read_total += bytesRead;
if(buffer[read_total - 1] == '\0'){
if(buffer[0] == '2'){
qDebug() << "收到python数据" << "\n";
WriteFile(hPipe, message_from_cpp.c_str(), static_cast<DWORD>(message_from_cpp.length() + 1), &bytesWritten, NULL);
}
else if(buffer[0] == '0'){
qDebug() << "python给出关闭信号" << "\n";
pipeStop = true;
}
read_total = 0;
}
}
} else {
Sleep(25);
}
} while (!pipeStop);
CloseHandle(hPipe);
qDebug() << "fifp通信结束" << "\n";
return true;
}
- 其次python编写命名管道通信代码
import win32file
import win32pipe
import time
def fifp_python():
hPipe = None
# 确保C++进程已创建管道并准备好接收数据
# Python进程尝试连接命名管道
pipStop = false
while not hPipe:
try:
# 尝试连接命名管道,如果管道还未创建,则会失败,此时等待一段时间后重试
hPipe = win32file.CreateFile(
"\\\\.\\pipe\\pretectPipe", # 与c++端保持一致
win32file.GENERIC_READ | win32file.GENERIC_WRITE, # 读写模式
0, # 不共享此管道
None, # 默认安全性
win32file.OPEN_EXISTING, # 打开已存在的管道
0, # 标准文件属性
None) # 无模板文件句柄
except OSError as ex:
if ex.winerror != 2: # 如果错误号不是2(文件未找到),则抛出异常
print("命名管道连接错误")
return False
time.sleep(0.025) # 管道未准备好,等待1秒后重试
while not pipStop:
# 检查管道中是否有数据
read_bytes, bytes_avail, _ = win32pipe.PeekNamedPipe(hPipe, 0)
buffer = b''
if bytes_avail > 0:
# 读取管道中的数据
data = win32file.ReadFile(hPipe, bytes_avail, None)[1]
buffer += data
# print(buffer[0])
# 检查是否接收到特定数据
if buffer == b'1\0':
print("Python接收C++数据成功")
# 发送响应数据
win32file.WriteFile(hPipe, b'2\0', None)
elif buffer == b'0\0':
print("Python接收到关闭信号")
win32file.WriteFile(hPipe, b'0\0', None)
win32file.CloseHandle(hPipe)
pipStop = True
else:
# 管道中无数据,短暂休眠以避免过度CPU使用
time.sleep(0.025)
return True
- 最后,在需要使用时在c++端先调用函数,再调用python端的函数,便可通过命名管道进行不同语言、进程间的通信进行数据交换