如何在Python ctypes中无需C函数直接修改iperf_test结构体指针的bind_port值?
可以直接修改结构体成员,无需额外C函数
当然可以直接修改!你不需要写额外的C setter函数,借助Python的ctypes库就能直接操作C结构体的成员。核心是在Python中映射C结构体的定义,然后把从C函数拿到的指针转换成对应的结构体指针类型,之后就能像操作普通Python对象一样修改成员了。
具体步骤:
在Python中定义对应C结构体的
ctypes.Structure类
要和C端的结构体字段完全对应,包括类型和顺序:from ctypes import Structure, c_int, POINTER, cdll class IperfTest(Structure): _fields_ = [ ("server_port", c_int), ("bind_port", c_int) ]指定C函数的返回类型
默认情况下,ctypes会把C函数的返回值当作int处理,在64位系统中这会截断指针导致错误,所以必须显式指定返回类型为结构体指针:self.lib = cdll.LoadLibrary("lib.so") # 告诉ctypes,iperf_new_test返回的是IperfTest结构体的指针 self.lib.iperf_new_test.restype = POINTER(IperfTest)获取结构体指针并解引用得到实例
调用函数后拿到指针,通过.contents属性解引用就能直接操作结构体成员:self._test_ptr = self.lib.iperf_new_test() # 得到结构体实例,之后可以直接读写成员 self._test = self._test_ptr.contents # 直接修改bind_port的值 self._test.bind_port = 5001 # 也可以读取当前成员值 print(f"当前server_port: {self._test.server_port}")
为什么之前的示例用setter函数?
很多示例用setter函数是因为它们没有在Python中映射结构体,只把返回值当作一个无类型的整数指针,没法直接访问成员。但只要正确映射结构体定义,完全可以省去额外的C函数,直接在Python端操作。
内容的提问来源于stack exchange,提问作者h3ct0r
相关产品推荐
相关产品推荐

