代码之家  ›  专栏  ›  技术社区  ›  h3ct0r

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

  •  1
  • h3ct0r  · 技术社区  · 7 年前

    我有一个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 回复  |  直到 7 年前
        1
  •  3
  •   ShadowRanger    7 年前

    对这就是为什么 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