gpt4 book ai didi

Python ctypes 和指针作为函数参数

转载 作者:行者123 更新时间:2023-11-28 17:46:54 26 4
gpt4 key购买 nike

我编写了一个 C 库来通过 USB 连接硬件设备,并且已经成功地将库与其他 C 代码一起使用,所以我知道它可以工作。我想从 Python 调用这个库,为此我需要通过引用传递一个结构,以便库可以修改它。结构定义:

typedef struct eventNode eventNode;
struct eventNode{
int channels;
int samples;
uint16_t** event;
eventNode* next;
eventNode* prev;
}

在 Python 中我定义了:

class eventNode(Structure):
pass

eventNode._fields_ = [("channels", c_int),
("samples", c_int),
("event",POINTER(POINTER(c_uint16))),
("prev",POINTER(eventNode)),
("next",POINTER(eventNode))]

我认为这是正确的。本质上,我用它来实现一个链表,我的库可以通过调用带有签名 void getFromCAEN(int, char*, eventNode**, eventNode**) 的方法来修改它。最后两个参数分别是指向列表头和尾的指针。我的 python 代码通过调用创建这些指针:

queueHead = POINTER(eventNode)()
queueTail = POINTER(eventNODE)()

最初应为 NULL(ctypes 中为 None),以便库知道列表为空。当我用这条线调用这个函数时

caenlib.getFromCAEN(handle,buff,byref(queueHead),byref(queueTail))

库应该形成一个链接列表,然后我尝试使用以下 block 对其进行索引:

cur = queueHead
while cur:
i+=1
print("event!",i)
print(addressof(cur))
print(cur.contents.channels,cur.contents.samples)
print(cur.contents.event)
print(cur.contents.next) #print next object in line
cur = cur.contents.next
print(cur) #this prints a different address for some reason

所有这些打印语句的输出是这样的:

event! 1
140486871191712
4 150
<__main__.LP_LP_c_ushort object at 0x7fc5a60d9200>
<__main__.LP_eventNode object at 0x7fc5a60d9170>
<__main__.LP_eventNode object at 0x7fc5a60d9290>

但问题是,即使我知道列表中应该有很多事件,它也只迭代一次然后就停止了。问题似乎出在最后几行,即使 cur 被分配给 cur.contents.next,地址似乎也从 0x...170 变成了 0x ...290 分配后。在此之后尝试取消引用 cur 会引发 NULL 指针异常。我想我在 Python 中遗漏了一些关于指针和赋值的东西,但我不确定该怎么做。

PS 对 cur.contents.channelscur.contents.samples 的访问返回了我对我能够访问的一个对象所期望的结果,表明它至少部分起作用。

最佳答案

您在 eventNode 的 ctypes 定义中翻转了 nextprev。因此,当您使用 next 时,您实际上得到的是 prevNULL 值。

不断变化的 LP_eventNode 地址是不相关的。这是每次访问 Structure 字段时创建的 Python 对象的地址。

from ctypes import *

class eventNode(Structure):
pass

eventNode._fields_ = [
("channels", c_int),
("samples", c_int),
("event", POINTER(POINTER(c_uint16))),
("next", POINTER(eventNode)),
("prev", POINTER(eventNode)),
]

_fields_ 被定义为一个tuplelist 以便保留用于计算每个字段的偏移量的顺序。类型中的 CField 描述符指定 ctypes 类型、大小和每个字段的偏移量。

关于Python ctypes 和指针作为函数参数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16844321/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com