You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在C#与Python进程间通过Named Pipe交换double数组?求技术指导

C#与Python通过命名管道交换Double数组实现方案

核心逻辑说明

命名管道本质是字节流传输通道,无法直接传递复杂数据类型。所以实现double数组交换的核心是:将数组序列化为字节数组传输,接收后再反序列化为原数组,同时需要先传递数组长度作为字节流的边界标识,避免接收方无法判断数据结束位置。


C#端实现(以服务端为例)

using System;
using System.IO.Pipes;
using System.Linq;

class PipeServer
{
    static void Main()
    {
        // 创建命名管道,名称需与Python端一致
        using (var pipeServer = new NamedPipeServerStream("DoubleArrayPipe", PipeDirection.InOut, 1))
        {
            Console.WriteLine("等待Python客户端连接...");
            pipeServer.WaitForConnection();
            Console.WriteLine("客户端已连接");

            try
            {
                // 1. 发送double数组
                double[] sendArray = { 1.1, 2.2, 3.3, 4.4 };
                // 先发送数组长度(4字节int),告知接收方要读取的元素数量
                int arrayLength = sendArray.Length;
                byte[] lengthBytes = BitConverter.GetBytes(arrayLength);
                pipeServer.Write(lengthBytes, 0, lengthBytes.Length);

                // 将每个double转成8字节,拼接成总字节数组发送
                byte[] dataBytes = sendArray.SelectMany(d => BitConverter.GetBytes(d)).ToArray();
                pipeServer.Write(dataBytes, 0, dataBytes.Length);
                Console.WriteLine($"已发送数组: {string.Join(", ", sendArray)}");

                // 2. 接收Python返回的数组
                byte[] recvLengthBytes = new byte[4];
                pipeServer.Read(recvLengthBytes, 0, 4);
                int recvLength = BitConverter.ToInt32(recvLengthBytes, 0);

                byte[] recvDataBytes = new byte[recvLength * 8];
                pipeServer.Read(recvDataBytes, 0, recvDataBytes.Length);
                double[] recvArray = new double[recvLength];
                for (int i = 0; i < recvLength; i++)
                {
                    recvArray[i] = BitConverter.ToDouble(recvDataBytes, i * 8);
                }
                Console.WriteLine($"收到返回数组: {string.Join(", ", recvArray)}");
            }
            catch (Exception ex)
            {
                Console.WriteLine($"出错: {ex.Message}");
            }
        }
    }
}

Python端实现(客户端)

先安装依赖:pip install pywin32

import win32pipe
import win32file
import struct

def main():
    # Windows命名管道完整路径格式:\\.\pipe\管道名
    pipe_name = r'\\.\pipe\DoubleArrayPipe'
    print("连接到C#服务端...")
    handle = win32file.CreateFile(
        pipe_name,
        win32file.GENERIC_READ | win32file.GENERIC_WRITE,
        0,
        None,
        win32file.OPEN_EXISTING,
        0,
        None
    )
    print("已连接到服务端")

    # 设置管道为消息读取模式
    win32pipe.SetNamedPipeHandleState(
        handle,
        win32pipe.PIPE_READMODE_MESSAGE | win32pipe.PIPE_WAIT,
        None,
        None
    )

    try:
        # 1. 接收C#发送的数组
        # 先读4字节获取数组长度
        length_bytes = win32file.ReadFile(handle, 4)[1]
        array_length = struct.unpack('<i', length_bytes)[0]

        # 读取对应长度的字节,解析为double数组(<表示小端字节序,与C#默认一致)
        data_bytes = win32file.ReadFile(handle, array_length * 8)[1]
        recv_array = struct.unpack(f'<{array_length}d', data_bytes)
        print(f"收到C#数组: {list(recv_array)}")

        # 2. 发送返回的double数组
        send_array = [5.5, 6.6, 7.7]
        # 先发送数组长度
        send_length = struct.pack('<i', len(send_array))
        win32file.WriteFile(handle, send_length)

        # 序列化数组并发送
        send_data = struct.pack(f'<{len(send_array)}d', *send_array)
        win32file.WriteFile(handle, send_data)
        print(f"已发送返回数组: {send_array}")
    except Exception as e:
        print(f"出错: {str(e)}")
    finally:
        win32file.CloseHandle(handle)

if __name__ == '__main__':
    main()

关键注意事项

  • 管道名称匹配:C#端可直接写管道名,Python端必须使用\\.\pipe\管道名的完整格式
  • 字节序统一:Windows系统默认小端字节序,C#的BitConverter和Python的struct都用小端模式(<标识),避免解析错误
  • 边界标识:必须先传递数组长度,否则接收方无法判断字节流的结束位置
  • 异常处理:管道连接、读写过程中可能出现断开、超时等问题,需添加捕获逻辑

内容的提问来源于stack exchange,提问作者Eli Ghaderi

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.09 02:30:58