Вопрос

I have a GetImageData function in a DLL:

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 ); 

in Python I import this DLL and establish the variables:

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

In MATLAB an array and pointer are defined:

img = uint8(zeros([roiW,roiH,nch]));
ptr = libpointer('uint8Ptr',img);

In PYTHON I think this is how it should be done for the Matlab equivalent, but this does not work and kills 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)

How do I correctly create an array and pointer than can be fed to my DLL?

Это было полезно?

Решение

Manually creating all the c_int and c_char_p instances is unnecessary. But set the function pointer's argtypes to enable type checking.

The ctypes._as_parameter_ attribute of NumPy arrays is a c_void_p. If you prefer more strict type safety, use POINTER(c_uint8) in argtypes and 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

I use from ctypes import * for convenience. You can import the wrapped C API into another module to get a clean namespace. It's common in Python to have one or more support modules and platform modules named with an initial underscore.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top