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

时间:2018-01-05 23:13:11

标签: python c pointers struct ctypes

我有一个C函数,它返回一个指向结构的指针:

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; 
};

我在互联网上看到的例子显示我需要使用一个接收指针来改变值的函数,例如在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函数?

1 个答案:

答案 0 :(得分:3)

是。这就是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