我在dll文件中有一个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 :(得分: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)
答案 1 :(得分:0)
以下是一个类型,void指针大小为8的数组,并且不正确。
data = ctypes.c_void_p*8
相反,您需要一些数据的实例。您可以使用像data = 'abcdefg'
这样的字节字符串。这将传递字母的ASCII值的8字节值加上空终止符。
如果data
是某种结构化数据,请考虑struct.pack:
>>> struct.pack('8B',1,2,3,4,5,6,7,8)
'\x01\x02\x03\x04\x05\x06\x07\x08'
c
,d
,timestamp
需要是C类型才能保存输出值:
c = ctypes.c_int()
d = ctypes.c_int()
timestamp = ctypes.c_ulong()
使用byref
将对这些实例的引用传递给函数,但首先最好声明参数类型以确保它们被正确地封送到C堆栈。
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))
使用以下方法查看输出值:
print c.value, d.value, timestamp.value