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

Python如何将PIL加载的图像转为c_void_p传递给C# DLL的IntPtr?

问题解答

1. Python端argtypes的确认

是的,Python调用C#导出的接收IntPtr的方法时,argtypes应该指定为ctypes.c_void_p——因为C#的IntPtr在非托管交互场景中对应C/C++的void*,而ctypes里的c_void_p正是用来表示这种通用指针类型的。

示例代码片段:

import ctypes

# 加载C#导出的DLL
my_dll = ctypes.CDLL("YourCSharpDll.dll")
# 假设导出的方法名为ProcessBitmap
my_dll.ProcessBitmap.argtypes = [ctypes.c_void_p]
my_dll.ProcessBitmap.restype = None  # 根据实际返回值调整

2. 从PIL.Image获取对应的c_void_p

PIL的Image对象本身没有直接暴露底层内存指针,需要先将图像转换为与C# Bitmap兼容的像素数据格式,再通过ctypes获取指针。以下是两种可行方案:

方案一:转为字节数组后获取指针

此方法需同时向C#传递图像宽、高、像素格式等参数,让C#端基于数据创建Bitmap:

from PIL import Image
import ctypes

# 加载图像并转为RGB格式(匹配C# Bitmap常见像素格式)
img = Image.open("test.jpg").convert("RGB")
width, height = img.size
# 获取图像字节数据
img_bytes = img.tobytes()

# 将字节数据转为ctypes缓冲区,再强转为c_void_p指针
img_buffer = ctypes.c_buffer(img_bytes)
img_ptr = ctypes.cast(img_buffer, ctypes.c_void_p)

# 此时img_ptr即可传递给C#的IntPtr参数

注意:C#端需使用Bitmap(int width, int height, int stride, PixelFormat format, IntPtr scan0)构造函数,才能基于传入的指针和参数正确创建Bitmap。

方案二:Windows环境下通过GDI+ API获取指针

如果运行环境是Windows,可借助win32系列库获取图像的HBitmap指针:

from PIL import Image
import ctypes
import win32gui
import win32api

img = Image.open("test.jpg").convert("RGB")
# 将PIL图像转为HBitmap
hbitmap = img.tobitmap()
# 读取BITMAP结构,解析出像素数据指针
bitmap_info = win32api.GetObject(hbitmap, 20)
bm_bits_ptr = ctypes.cast(bitmap_info[-4:], ctypes.c_void_p)

# 传递bm_bits_ptr给C#方法
# 使用完后需释放资源避免泄漏
win32gui.DeleteObject(hbitmap)

额外注意事项

  • 必须保证Python端与C#端的像素格式一致,比如Python转RGB,C#就用PixelFormat.Format24bppRgb,否则会出现图像颜色错乱或解析失败。
  • 如果C#方法是直接接收Bitmap对象的指针(而非像素数据指针),上述方法不适用。这种场景建议改为传递像素数据指针+宽高参数的方式,更适配UnmanagedExports的交互逻辑。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.24 00:42:36