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

如何快速将C#的System.UInt16[,]二维数组转换为Python列表?

快速转换C# UInt16二维数组到Python列表的方案

核心思路:直接操作连续内存块

C#的System.UInt16[,]是行优先连续存储的二维数组,无需逐元素遍历,直接读取整块内存是效率最高的方式。

方法1:基于pythonnet的内存拷贝实现

如果使用pythonnet(clr模块)调用C# DLL,结合.NET的Marshal类直接复制内存到Python,再转成目标格式:

import clr
import numpy as np
from System import UInt16
from System.Runtime.InteropServices import Marshal

# 假设已获取C#二维数组:csharp_array = ...
rows = csharp_array.GetLength(0)
cols = csharp_array.GetLength(1)

# 获取数组内存起始指针,计算总字节数
ptr = Marshal.UnsafeAddrOfPinnedArrayElement(csharp_array, 0)
total_bytes = rows * cols * 2  # UInt16占2字节

# 批量读取内存到字节对象
bytes_data = Marshal.Copy(ptr, bytearray(total_bytes), 0, total_bytes)
# 转numpy数组并重塑形状,最后转Python列表
np_array = np.frombuffer(bytes_data, dtype=np.uint16).reshape(rows, cols)
python_list = np_array.tolist()

方法2:用ctypes直接映射内存(已知内存地址时)

如果能从C# DLL获取数组的原始内存地址,可通过ctypes直接映射内存,实现零拷贝转换:

import ctypes
import numpy as np

# 假设已获取数组内存地址ptr(整数)、行数rows、列数cols
ptr = ...
rows = ...
cols = ...

# 用ctypes创建指向目标内存的数组
c_array = (ctypes.c_uint16 * (rows * cols)).from_address(ptr)
# 映射为numpy数组并重塑,最后转列表
np_array = np.ctypeslib.as_array(c_array).reshape(rows, cols)
python_list = np_array.tolist()

效率提升原因

  • 跳过逐元素遍历和类型转换,直接批量操作内存,时间复杂度从O(n*m)降至接近O(1)的内存拷贝/映射。
  • numpy的frombuffer和as_array都是极低开销的操作,远快于fromiter或手动遍历。

注意事项

  • 确保C#数组内存处于固定(pinned)状态,避免GC移动内存导致指针失效;使用pythonnet时UnsafeAddrOfPinnedArrayElement会自动处理固定逻辑。
  • 仅适用于C#多维数组UInt16[,],交错数组UInt16[][]内存不连续,无法用此方法。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.09 02:25:23