python 指针数组,将C指针数组转换为结构的Python数组

I am writing a Python app that makes use of PulseAudio API. The implementation is heavily using callbacks written in Python and invoked by PulseAudio's C code.

The most information is passed into the callback by a specific structure, for instance pa_sink_info, which is defined in C as follows:

typedef struct pa_sink_info {

const char *name;

uint32_t index;

const char *description;

pa_sample_spec sample_spec;

pa_channel_map channel_map;

uint32_t owner_module;

pa_cvolume volume;

int mute;

uint32_t monitor_source;

const char *monitor_source_name;

pa_usec_t latency;

const char *driver;

pa_sink_flags_t flags;

pa_proplist *proplist;

pa_usec_t configured_latency;

pa_volume_t base_volume;

pa_sink_state_t state;

uint32_t n_volume_steps;

uint32_t card;

uint32_t n_ports;

pa_sink_port_info** ports;

pa_sink_port_info* active_port;

uint8_t n_formats;

pa_format_info **formats;

} pa_sink_info;

From this structure it's very easy to get scalar values, eg.:

self.some_proc(

struct.contents.index,

struct.contents.name,

struct.contents.description)

But I have a difficulty dealing with ports and active_port, which in Python are described as:

('n_ports', uint32_t),

('ports', POINTER(POINTER(pa_sink_port_info))),

('active_port', POINTER(pa_sink_port_info)),

Here n_ports specifies number of elements in ports, which is a pointer to array of pointers to structures of type pa_sink_port_info. Actually, I don't even know how I can convert these to Python types at all.

What is the most efficient way of converting ports into Python dictionary containing pa_sink_port_info's?

解决方案

Solving this problem required careful reading of Python's ctypes reference. Once the mechanism of ctypes type translation implementation was clear, it's not so difficult to get to the desired values.

The main idea about pointers is that you use their contents attribute to get to the data the pointer points to. Another useful thing to know is that pointers can be indexed like arrays (it's not validated by the interpreter, so it's your own responsibility to make sure it is indeed an array).

For this particular PulseAudio example, we can process the ports structure member (which is a pointer to array of pointers) as follows:

port_list = []

if struct.contents.ports:

i = 0

while True:

port_ptr = struct.contents.ports[i]

# NULL pointer terminates the array

if port_ptr:

port_struct = port_ptr.contents

port_list.append(port_struct.name)

i += 1

else:

break

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值