2016-11-22 97 views
0

我在定義一個DLL文件中的C函數如下:如何通過ctypes將void *數組傳遞給C函數?

myFunction(const int a, long b, void * data, unsigned int * c, unsigned int * d, unsigned long * timestamp) 

參數:

[in]: a 
[in]: b 
[out]: data, which is a pointer to a buffer that is maximum of 8 bytes 
[out]: c, points to a buffer that receives data message length 
[out]: d, pointer to a buffer which receives a message flag 
[out]: timestamp, pointer to a buffer which receives message timestamp 

我的Python代碼如下:

import ctypes 

dllhandle = ctypes.WinDLL("dllFile.dll") 

a = 1 
b = 1738 
data = ctypes.c_void_p*8 
c = 0 
d = 0 
timestamp = 0 

dllhandle.myFunction(a, b, data, c, d, timestamp) 

當我跑我的Python代碼,我得到以下錯誤:

ctypes.ArgumentError: argument 3: <type 'exceptions.TypeError'>: Don't know how to convert parameter 3. 

我想這與我如何創建我的數據緩衝區指針數組有關。創建數據緩衝區的正確方法是什麼?

回答

0

你應該使用一個字符數組來傳遞你的數據。我寫了這個腳本,可以幫助你:

""" 
extern "C" void your_func(void* buffer, int size); 
""" 
# For Python 2.7 
import ctypes 

BUFFER_SIZE = 256 

# Importing dll 
dll = ctypes.CDLL("dllFile.dll") 

# Defining C-arguments and output 
buffer_c_type = lambda chars: (ctypes.c_char * BUFFER_SIZE)(*map(ctypes.c_char, chars)) 
size_c_type = ctypes.c_int 
restype = None # None is for 'void' as the result of your function in C 

# Creating C-arguments having Python variables 'buffer' and 'BUFFER_SIZE' 
buffer = "qwdeasdvwergb" 
c_buffer = buffer_c_type(buffer) 
c_size = size_c_type(BUFFER_SIZE) 

# Extracting your_func from dll and setting the type of returning value 
your_func = dll["your_func"] 
your_func.restype = restype 

# Running your_func 
your_func(c_buffer, c_size) 
0

以下是一個類型,void指針數組的大小爲8,並且是不正確的。

data = ctypes.c_void_p*8 

取而代之,您需要一些數據的實例。您可以使用像data = 'abcdefg'這樣的字節字符串。這會傳遞一個8字節的ASCII值的字母加上一個空終止符。

如果data是某種形式的結構化數據,考慮struct.pack

>>> struct.pack('8B',1,2,3,4,5,6,7,8) 
'\x01\x02\x03\x04\x05\x06\x07\x08' 

cdtimestamp需要一個C類持有一個輸出值:

c = ctypes.c_int() 
d = ctypes.c_int() 
timestamp = ctypes.c_ulong() 

使用byref到將這些實例的引用傳遞給函數,但首先聲明參數類型以確保它們正確地編組到C堆棧是一個好主意。

print c.value, d.value, timestamp.value 

from ctypes import * # for brevity 
dllhandle.myFunction.argtypes = c_int,c_long,c_void_p,POINTER(c_int),POINTER(c_int),POINTER(c_ulong) 
dllhandle.myFunction.restype = None # for void return 

dllhandle.myFunction(a, b, data, byref(c), byref(d), byref(timestamp)) 

查看與輸出值