1

我正在编写一个使用 PulseAudio API 的 Python 应用程序。该实现大量使用用 Python 编写并由 PulseAudio 的 C 代码调用的回调。

大多数信息通过特定结构传递到回调中,例如pa_sink_info,在 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)

但是我在处理portsand时遇到了困难active_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 类型。

转换成包含's 的portsPython 字典的最有效方法是什么?pa_sink_port_info

4

1 回答 1

0

解决这个问题需要仔细阅读 Python 的ctypes 参考。一旦ctypes明确了类型转换实现的机制,想要得到想要的值就不是那么难了。

关于指针的主要思想是您使用它们的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
于 2013-12-30T17:03:24.227 回答