我有一个C共享库,它的函数只有一个参数。 此参数是指向具有两个字段的结构的指针
typedef struct
{
uint8_t *p_data; // Pointer to a fixed lenth buffer (100 bytes)
uint16_t len; // number of valid bytes in the buffer (range 1-100)
} data_t;
我需要在python3脚本中设置一个100字节的缓冲区(我使用的是3.7.2/3.7.3), 加载库并调用此函数
int
fn_convert_buffer(data_t *data_p)
{
...
}
我的python3ctypes调用尝试命中不兼容的类型
import ctypes as ct
# load the library, etc...
# lib_cdll = ct.CDLL(mySharedLib)
def c_py_fn_convert_buffer(b_p):
global lib_cdll
val = lib_cdll.fn_convert_buffer(ct.byref(b_p))
return int(val)
data_a = bytearray(100)
# Initialize the buffer with data.
uint8_p = ct.c_uint8 * len(data_a)
class BufferStruct_t (ct.Structure):
_pack_ = 1
_fields_ = [
("p_data", ct.POINTER(ct.c_uint8 * len(data_a))),
("len", ct.c_uint16)
]
data_buf = BufferStruct_t(uint8_p.from_buffer(data_a), ct.c_uint16(8))
# TypeError: incompatible types, c_ubyte_Array_100 instance
# instead of LP_c_ubyte_Array_100 instance
# Call C function in shared-library: int fn_convert_buffer(data_t *data_p);
z = c_py_fn_convert_buffer(data_buf)
我需要帮助来理解我在上面的BufferStruct_t
定义中遗漏了什么。from_buffer
应该得到一个指向缓冲区的指针,但它似乎得到了c_ubyte_ARRAY_100
一个byref()
也不起作用
data_buf = BufferStruct_t(ct.byref(uint8_p.from_buffer(data_a)), ct.c_uint16(8))
# TypeError: expected LP_c_ubyte_Array_100 instance, got CArgObject
为了测试我的流的基础知识,我做了一个示例,分别发送缓冲区和长度参数
def c_py_fn_convert_data(d_p,l):
global lib_cdll
val = lib_cdll.fn_convert_data(ct.byref(d_p),ct.c_uint32(l))
return int(val)
test_a = ct.c_uint8 * len(data_a)
# Call C function in shared-library:
# int fn_convert_data(uint8_t *data_p, uint32_t length);
z = c_py_fn_convert_data(test_a.from_buffer(data_a), 8)
这个简化的案例有效
如何构建一个python3对象,该对象包含对共享库函数所期望的缓冲区的引用
更新两个有效的变体。
更新1根据我稍后阅读的内容尝试了cast
(我不会轻易地:-)
)
改变了
data_buf = BufferStruct_t(uint8_p.from_buffer(data_a), ct.c_uint16(8))
转换为引用特定长度数组的指针
data_buf = BufferStruct_t(cast(uint8_p.from_buffer(data_a),
ct.POINTER(ct.c_uint8 * len(data_a))),
ct.c_uint16(8))
根据马克的答案更新2。
更改_field_
("p_data", ct.POINTER(ct.c_uint8 * len(data_a))),
一个简单的指针形式
("p_data", ct.POINTER(ct.c_uint8)),
两种方法都有效。
不过,我很想知道这两种方法中哪一种更安全/正确地处理ctypes。
您的结构定义声明了指向数组的指针,而不是C结构中的简单指针。下面是一个简单的DLL实现的工作示例,其中函数对数据求和:
测试.c
测试.py
输出:
相关问题 更多 >
编程相关推荐