将C指针数组转换为结构的Python数组 [英] Convert C array of pointers to Python array of structures

查看:233
本文介绍了将C指针数组转换为结构的Python数组的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在编写一个使用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)

但是我很难处理portsactive_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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆