将C指针数组转换为结构的Python数组 [英] Convert C array of pointers to Python array of structures
问题描述
我正在编写一个使用PulseAudio API的Python应用程序.该实现大量使用Python编写的回调,并由PulseAudio的C代码调用.
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.
大多数信息通过特定的结构(例如pa_sink_info
)传递到回调中,该结构为
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)
但是我很难处理ports
和active_port
,它们在Python中被描述为:
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)),
此处n_ports
指定ports
中的元素数,这是指向pa_sink_port_info
类型的结构的指针数组的指针.实际上,我什至都不知道如何将它们转换为Python类型.
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.
将ports
转换为包含pa_sink_port_info
的Python字典的最有效方法是什么?
What is the most efficient way of converting ports
into Python dictionary containing pa_sink_port_info
's?
推荐答案
要解决此问题,需要仔细阅读Python的 ctypes参考.一旦明确了ctypes
类型转换实现的机制,就不难达到所需的值.
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.
关于指针的主要思想是使用它们的contents
属性来获取指针所指向的数据.要知道的另一件有用的事情是,指针可以像数组一样被索引(解释器未对其进行验证,因此确保它确实是数组是您的责任).
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).
对于这个特定的PulseAudio示例,我们可以按以下方式处理ports
结构成员(它是指向指针数组的指针):
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
这篇关于将C指针数组转换为结构的Python数组的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!