在不使用 C 函数的情况下更新 ctypes python 中结构指针的值

Update values of a struct pointer in ctypes python without using a C function

我有一个 C 函数 returns 一个指向结构的指针:

struct iperf_test *
iperf_new_test()
{
    struct iperf_test *test;

    test = (struct iperf_test *) malloc(sizeof(struct iperf_test));
    ...
    return test;
}

通过以下方式从 Python 调用此函数:

self.lib = cdll.LoadLibrary("lib.so")
self._test = self.lib.iperf_new_test()

该结构有一些值,例如:

struct iperf_test
{
    int       server_port;
    int       bind_port; 
};

我在 Internet 上看到的示例表明我需要使用接收指针的函数来更改值,例如 python:

self.lib.iperf_set_test_server_port(self._test, int(port))

在 C 中:

void
iperf_set_test_server_port(struct iperf_test *ipt, int srv_port)
{
    ipt->server_port = srv_port;
}

有没有办法 直接 bind_port 更改值 而无需使用 C 函数?

是的。这就是 ctypes 支持 defining your own structs 和定义函数原型的原因。

您需要对结构进行 Python 级别定义,例如:

from ctypes import Structure, c_int, POINTER

class iperf_test(Structure):
    _fields_ = [("server_port", c_int),
                ("bind_port", c_int)]

然后,在调用您的 C 函数之前,您 set its restype 正确地:

# Load library as normal
self.lib = cdll.LoadLibrary("lib.so")
# New, so Python knows how to interpret result
self.lib.iperf_new_test.restype = POINTER(iperf_test)
# Call, and Python returns pointer to Python definition of struct
self._test = self.lib.iperf_new_test()

现在您可以使用它 by dereferencing(使用 [0] 完成,因为 Python 缺少 * 指针取消引用运算符)并直接在取消引用的结构上设置属性:

self._test[0].bind_port = new_bind_port