C++与Python通过命名管道进行通信

最近写项目用到了C++与Python,两个之间需要通信,所以就记录一下自己的学习过程防止自己忘记,代码主要参考这篇博主的博客,上链接:

参考博客

我主要需要的是C++发送,Python来接收,稍微改了一下,代码如下:

C++发送:

#include <Windows.h>
#include <iostream>

//发送数据的字节数
#define BUF_SIZE 2

using namespace std;

int main()
{
	HANDLE h_pipe;
	char buf_msg[] = "1";//主要发送的数据
	DWORD num_rcv;//实际收到的字节数
	cout << "Try to connect named pipe..." << endl;
	//连接命名管道
	if (WaitNamedPipe("\\\\.\\pipe\\test_pipe", NMPWAIT_WAIT_FOREVER))
	{
		//打开指定的命名管道
		h_pipe = CreateFile("\\\\.\\pipe\\test_pipe", GENERIC_WRITE, 0, nullptr, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, nullptr);
		if (h_pipe == INVALID_HANDLE_VALUE)
		{
			cerr << "Failed to open the appointed named pipe!Error code:" << GetLastError() << endl;
			system("pause");
			return 1;
		}
		else
		{
			if (WriteFile(h_pipe, buf_msg, BUF_SIZE, &num_rcv, nullptr))
			{
				cout << "Message sent successfully..." << endl;
			}
			else
			{
				cerr << "Failed to send message!Error code:" << GetLastError() << endl;
				CloseHandle(h_pipe);
				system("pause");
				return 1;
			}
		}
		CloseHandle(h_pipe);
	}
	system("pause");
	return 0;
}

Python接收:

import win32file
import win32pipe
import struct
import threading


def recv_pipe(PIPE_NAME, PIPE_BUFFER_SIZE):
    while True:
        named_pipe = win32pipe.CreateNamedPipe(PIPE_NAME,
                                               win32pipe.PIPE_ACCESS_DUPLEX,
                                               win32pipe.PIPE_TYPE_MESSAGE | win32pipe.PIPE_WAIT | win32pipe.PIPE_READMODE_MESSAGE,
                                               win32pipe.PIPE_UNLIMITED_INSTANCES,
                                               PIPE_BUFFER_SIZE,
                                               PIPE_BUFFER_SIZE, 500, None)
        try:
            while True:
                try:
                    win32pipe.ConnectNamedPipe(named_pipe, None)
                    data = win32file.ReadFile(named_pipe, PIPE_BUFFER_SIZE, None)
                    if data is None:
                        continue
                    # print("Received msg:", data)
                    recv_msg = struct.unpack('<2s', data[1])
                    recv_msg = recv_msg[0].decode("utf-8")
                    print("Parsed message:", recv_msg)
                except BaseException as e:
                    print("Exception1:", e)
                    break
        finally:
            try:
                win32pipe.DisconnectNamedPipe(named_pipe)
            except BaseException as e:
                print("Exception2:", e)
                break


if __name__ == "__main__":
    pipe_name = r"\\.\pipe\test_pipe"
    pipe_buffer_size = 65535
    receive_thread = threading.Thread(target=recv_pipe, args=(pipe_name, pipe_buffer_size))
    receive_thread.start()

说明:

C++程序

  1. C++程序中的宏定义BUF_SIZE可以当作你要写入数据的字节数。定义的DWORD类型的num_rcv是实际收到的字节数,这个好像没什么影响不需要管。BUF_SIZE的话根据你要传的数据来定吧,我这里只是传一个信号,所以没设太大,就设成了2。参考博客中说python收到数据后面还有一堆乱码可能是BUF_SIZE设得比较大(1024),而传输的数据本身只有几个字节,我本人试过那样确实后面会有一堆别的东西,当我设成和数据大小一样时就没有了,所以我猜测可能是BUF_SIZE设得比较大。
  2. 然后就是代码中连接命名管道那句如图:
    在这里插入图片描述
    图中框出的两个地方要一致,不一致就发不出去。
    WaitNamedPipe主要来等待命名管道的出现,这里我命名的是test_pipe,如果等到管道即WaitNamedPipe返回true,下来就打开指定的命名管道即下面这句:
//打开指定的命名管道
h_pipe = CreateFile("\\\\.\\pipe\\test_pipe", GENERIC_WRITE, 0, nullptr, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, nullptr);

Python程序

  1. Python的接收程序我是用线程来接收,方便多线程运行。
  2. 收到数据后,用struct库对数据进行解析,data是一个元组,第一个元素是0(我也不知道为什么是0),第二个元素就是我发送的数据,所以取得data[1],这样得到的recv_msg是一个二进制字符串,print的话前面带有b,强迫症的我为了看起来和普通字符串一样,就对字符串以utf-8做了解码

在这里插入图片描述

运行结果:

先启动python准备接收,然后启动C++程序发送
发送完成:

接收结果:
在这里插入图片描述
接收到发送的数据1,通信没问题,下面的异常应该是程序发送完成后关闭线程句柄导致的,不过影响不大。

  • 5
    点赞
  • 20
    收藏
    觉得还不错? 一键收藏
  • 4
    评论
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值