如何从c函数签名确定python3 ctypes.argtypes?

ymdaylpp  于 2021-07-13  发布在  Java
关注(0)|答案(1)|浏览(460)

我正在写一个ctypes接口到第三方dll(我没有对dll的控制)。
我的代码似乎有效,但我担心我正在设置 .argtypes 错了。
我试图调用的c函数的签名是:

int GetData(unsigned short option, unsigned char* buffer, int bufferLength, int &actualLength);
``` `option` 指示请求的数据类型, `buffer` 指向我提供的缓冲区, `bufferLength` 缓冲区的长度(字节)。
dll函数写入缓冲区,并将实际写入的字节数放入缓冲区 `actualLength` .
我的代码:

import ctypes

dll = ctypes.CDLL("dll_name.dll")

def GetData(option):

BUFSIZE = 6

buf = bytearray(BUFSIZE)

ptr_to_buf = (ctypes.c_char*len(buf)).from_buffer(buf)

actualLength = ctypes.c_int()

dll.GetData.argtypes = (ctypes.c_ushort, 
                        ctypes.c_char_p, 
                        ctypes.c_int, 
                        ctypes.POINTER(ctypes.c_int))

dll.GetData.restype = int

dll.GetData(option, 
            ptr_to_buf, 
            BUFSIZE, 
            ctypes.byref(actualLength))

return (buf, actualLength.value)
打电话给 `GetData()` 准确地反映。argtype?
可以通过吗 `ptr_to_buf` 作为一个 `ctypes.c_char_p` 就像我在这里做的那样?
通过考试可以吗 `ctypes.byref` 变成一个 `ctypes.POINTER` 就像我在这里做的那样?
什么时候需要使用 `.pointer` 而不是 `.byref?` 我看过ctype的文件,我知道他们说 `.byref` 速度更快,但我不清楚什么时候 `.pointer` 是需要的。
我还做错什么了吗?
brqmpdu1

brqmpdu11#

.argtypes 很好。你可能想要 POINTER(c_ubyte) 完全同意原型,但通常 c_char_p 更容易相处。
像我在这里做的那样把ptr\u作为ctypes.c\u字符传给\u buf可以吗?
对。数组作为相同元素类型的指针传递。
像我在这里所做的那样,将ctypes.byref传递给ctypes.pointer可以吗?
对。
何时需要使用.pointer而不是.byref?我确实读过ctype文档,我知道他们说。byref更快,但我不清楚什么时候需要。指针。
创建 pointer 当你需要一个具体的指针。我很少使用 pointer . 假设你用c语言编写了这段代码,并且有理由模仿它:

int x = 5;
int* y = &x;

python的等价物是:

x = c_int(5)
y = pointer(x)

我还做错什么了吗? .restype 应该有一个 ctype 类型。 .restype = c_int 是正确的。

相关问题