我在DLL中有一个GetImageData函数:
int GetImageData ( const char * name , int ID , const char * strLibPath , int Lvl , int rbeg , int rend , int cbeg , int cend , int ZLayer , unsigned char * ImgBuffer );
在Python中我导入这个DLL并建立变量:
import ctypes,numpy
from ctypes import *
Wlib = ctypes.WinDLL('C:\\...\\Wsl.dll')
GetImage=Wlib["GetImage"]
name =c_char_p(fname)
ID =c_int(0)
strLibPath=c_char_p(LibPath)
Lvl =c_int(0)
rbeg =c_int(100)
rend =c_int(1099)
cbeg =c_int(5500)
cend =c_int(6499)
ZLayer =c_int(0)
nBpp=24
nch = nBpp/8
roiW = 6499-5500+1
roiH = 1099-100+1
在MATLAB中定义了一个数组和指针:
img = uint8(zeros([roiW,roiH,nch]));
ptr = libpointer('uint8Ptr',img);
在PYTHON中我认为这是应该如何为Matlab等效做的,但这不起作用并杀死Python:
img = numpy.zeros([roiW,roiH,nch],dtype=ctypes.c_int8)
ptr=img.ctypes.data_as(ctypes.POINTER(ctypes.c_int8))
[status, fname, fpath, img]=GetImage(name,ID,strLibPath,Lvl,rbeg,rend,cbeg,cend,ZLayer, ptr)
如何正确创建一个数组和指针,而不是可以输入到我的DLL?
答案 0 :(得分:2)
手动创建所有c_int
和c_char_p
实例是不必要的。但是设置函数指针的argtypes
以启用类型检查。
NumPy数组的ctypes._as_parameter_
属性为c_void_p
。如果您更喜欢更严格的类型安全,请使用POINTER(c_uint8)
和argtypes
中的data_as
。
from ctypes import *
import numpy as np
__all__ = ['GetImage']
# WinDLL is stdcall; use CDLL for cdecl.
Wlib = WinDLL(r'C:\...\Wsl.dll')
Wlib.GetImage.argtypes = ([c_char_p, c_int, c_char_p] +
[c_int] * 6 +
[c_void_p])
def GetImage(name, ID, strLibPath, Lvl=0,
rbeg=100, rend=1099,
cbeg=5500, cend=6499,
ZLayer=0, nBpp=24):
roiW = cend - cbeg + 1
roiH = rend - rbeg + 1
nch = nBpp // 8
img = np.zeros([roiW, roiH, nch], dtype=np.uint8)
ImgBuffer = img.ctypes
status = Wlib.GetImage(name, ID, strLibPath, Lvl,
rbeg, rend, cbeg, cend,
ZLayer, ImgBuffer)
# test status
return img
为方便起见,我使用from ctypes import *
。您可以将包装的C API导入另一个模块以获得干净的命名空间。在Python中通常有一个或多个以初始下划线命名的支持模块和平台模块。