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

