使用ctypes向C++库传递numpy图像数组遇访问冲突问题求助
问题
我想借助Spetric的Photoshop-Plugin-Host DLL实现用Python运行Photoshop插件,需要把OpenCV加载的图像传入该DLL的pspiSetImage函数。我能读C++代码但不会写,也没法编译修改DLL来直接从文件名加载图像。
多次尝试相关方案后,都出现OSError: exception: access violation writing 0x00000000错误,试过__array_interface['data'][0]、ctypes.data_as等方法,还是解决不了。附上当前代码和函数定义,求指引解决方向。
函数定义(C++)
pspiSetImage(TImgType type, int width, int height, void *imageBuff, int imageStride, void *alphaBuff = 0, int alphaStride = 0);
当前Python代码
import ctypes import cv2 plugins = {} def main(args=None): plugin_host = ctypes.CDLL('.\pspiHost.dll') plugin_host.pspiSetPath(".\8bf filters\") # 随便用一张图测试,我用了带透明通道的PNG im = cv2.imread('.\fish.png', cv2.IMREAD_UNCHANGED) array = im.ctypes.data_as(ctypes.POINTER(ctypes.c_void_p)) width = im.shape[0] height = im.shape[1] # 第一个参数传1代表RGBA格式,我用的是带透明通道的PNG plugin_host.pspiSetImage(ctypes.c_int(1), ctypes.c_int(width), ctypes.c_int(height), array, ctypes.c_int(0)) if __name__=='__main__': main()
解决方向指引
强制匹配函数调用约定与参数类型:
- 必须显式定义
pspiSetImage的函数原型,避免因调用约定不匹配导致栈错误。示例:# 假设返回值为int,需根据实际DLL返回类型调整 PSPISetImageFunc = ctypes.CFUNCTYPE(ctypes.c_int, ctypes.c_int, ctypes.c_int, ctypes.c_int, ctypes.c_void_p, ctypes.c_int, ctypes.c_void_p, ctypes.c_int) plugin_host.pspiSetImage = PSPISetImageFunc(plugin_host.pspiSetImage) - 给
pspiSetPath指定参数类型,同时修正路径转义问题:plugin_host.pspiSetPath.argtypes = [ctypes.c_char_p] # 用原始字符串或编码传递路径 plugin_host.pspiSetPath(r".\8bf filters\".encode('utf-8'))
- 必须显式定义
修正图像通道顺序:
OpenCV加载的RGBA图像通道顺序为BGRA,若TImgType=1对应标准RGBA格式,需转换通道顺序:if im.shape[2] == 4: im = cv2.cvtColor(im, cv2.COLOR_BGRA2RGBA)修正宽高参数顺序:
OpenCV图像的shape是(height, width, channels),当前代码宽高搞反了,应调整为:height = im.shape[0] width = im.shape[1]修正图像指针传递方式:
无需转成POINTER(c_void_p),直接传递原始数据指针即可:image_buff = im.ctypes.data_as(ctypes.c_void_p)设置正确的Stride参数:
imageStride是单行列的字节数,RGBA格式下应为width * 4,传0会导致内存越界:image_stride = width * 4确认透明通道传递逻辑:
若TImgType=1是将Alpha通道与颜色数据合并为RGBA单buffer,无需单独传alphaBuff;若为分离格式,需拆分通道后传递,需确认TImgType的具体定义。
内容的提问来源于stack exchange,提问作者LeviFiction
相关产品推荐
相关产品推荐

