2013-09-28 120 views
1

我正在编写一个使用PulseAudio API的Python应用程序。该实现大量使用用Python编写并由PulseAudio的C代码调用的回调函数。将C数组指针转换为Python数组结构

最多的信息被传递到由特定结构的回调,例如pa_sink_info,这是defined用C如下:

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; 

从这个结构是很容易得到标值,例如:

self.some_proc(
    struct.contents.index, 
    struct.contents.name, 
    struct.contents.description) 

但我必须处理portsactive_port,困难这在Python中被描述为:

('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类型。

ports转换成包含pa_sink_port_info的Python字典的最有效方法是什么?

回答

0

解决这个问题需要仔细阅读Python的ctypes reference。一旦​​类型翻译实现的机制很明确,达到理想值并不难。

有关指针的主要想法是,您使用它们的contents属性来获取指针指向的数据。另一个有用的知识是指针可以像数组一样编制索引(它不会被解释器验证,所以确保它是一个真正的数组是你自己的责任)。

对于这个特定的PulseAudio例子中,我们可以处理ports结构构件(这是一个指向指针的数组)如下:

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