如何在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
相关产品推荐
相关产品推荐

