Python Numpy数组Ctypes指针

时间:2014-02-10 23:31:57

标签: python matlab numpy ctypes

我在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?

1 个答案:

答案 0 :(得分:2)

手动创建所有c_intc_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中通常有一个或多个以初始下划线命名的支持模块和平台模块。