如何在Python中使用GLib.Array? [英] How can I work with a GLib.Array in Python?

查看:94
本文介绍了如何在Python中使用GLib.Array?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在为Rhythmbox编写插件,其中的信号引发了GArray类型的对象的传递. GLib数组的文档向我展示了一些我感兴趣的方法,但无法访问.

I am writing a plugin for Rhythmbox, wherein a signal raised is passing in an object of type GArray. The documentation for GLib Arrays shows me a few methods I am interested in, but am unable to access.

例如, g_array_index 可以给我一个GArray中的 nth 项,但是我无法调用它. GArray对象也没有显示任何有用的方法.

For example, g_array_index can get me the nth item in a GArray, but I am unable to call it. The GArray object doesn't show me any useful methods either.

要了解我的意思,请在Python控制台中执行以下操作:

To see what I mean, do this in a Python console:

from gi.repository.GLib import Array
x = Array()
dir(x)

这是dir(x)的输出

Here is the output of dir(x)

['__class__', '__delattr__', '__dict__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__gt__', '__gtype__', '__hash__', '__info__', '__init__', '__le__', '__lt__', '__module__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '__weakref__', '_free_on_dealloc', 'copy', 'data', 'len']

我看不到其中有任何从数组中读取的方法,也没有有关g_array_index或GLib Arrays文档页面上提到的任何其他方法的信息.我也尝试过

I see no methods in there read from the array, and nothing about the g_array_index or any other methods mentioned on the GLib Arrays documentation page. I also tried

    for a in x:
        print a

还有

list(x)

但是我收到一个错误:

TypeError: 'Array' object is not iterable

尝试x [0]可以做到这一点:

Attempting x[0] gives this:

TypeError: 'Array' object does not support indexing

len属性给出了预期的数组长度.

The len property gives the length of the array as is expected.

data属性提供了此

如何处理正在传递的GLib.Array?

How can I work with this GLib.Array that I am being passed?

我正在运行Python 2.7.4

I am running Python 2.7.4

推荐答案

简介

在这个答案中,我将尝试总结我对这个问题的了解,并提供一种解决方案,该解决方案可以解决出现此问题的某些情况.不幸的是,在某些情况下,似乎还没有现成的解决方案,尽管我认为可以对Python GI模块进行修改以启用变通办法(请参见下面的结束思想).

Introduction

In this answer, I'll attempt to summarize what I've learned about this problem and provide a solution that can address some situations in which this problem arises. Unfortunately, in some cases, there seems to be no ready solution, though I think the Python GI module could be modified to enable workarounds (see Closing Thoughts, below).

核心问题是GArray只是围绕malloc()realloc()free()的相当薄的包装.除此之外,它还增加了一些功能,例如引用计数和对零终止的内置支持.但是,它缺少的一项显着功能是对数组元素类型的任何了解!这意味着Python GI(GObject自省)模块无法适应任意的GArray以用作Python序列类型,而没有有关GArray包含的内容的进一步信息.

The core issue is that GArray is only a rather thin wrapper around malloc(), realloc(), and free(). Beyond that, it adds a couple features, such as ref-counting and built-in support for zero-termination. However, a notable feature it lacks is any knowledge of the array's element type! What this means is that the Python GI (GObject Introspection) module is unable to adapt an arbitrary GArray to work as a Python sequence type, without further information about what the GArray contains.

gi模块支持的使用GArray的方法是生成一个.typelib文件,该文件包含它需要的其他信息,以适应每个特定的GArray实例.幸运的是,有一个工具链可以帮助您直接从源代码生成这些文件.

The method of using GArrays that's supported by the gi module is to generate a .typelib file, which contains the additional information it needs, in order to adapt each specific GArray instance. Fortunately, there's a toolchain that exists to help you generate these files directly from your sourcecode.

要使用此方法,请首先根据此处定义的格式用注释块记录源代码:

To use this method, start by documenting your source code with comment blocks according to the format defined here:

接下来,运行g-ir-scanner工具,以生成.gir文件.可以在以下位置找到该工具的文档:

Next, run the g-ir-scanner tool, in order to generate a .gir file. The docs for this tool can be found here:

最后,可以使用g-ir-compiler工具创建.typelib文件.记录在这里:

Finally, the g-ir-compiler tool can be used to create the .typelib file. It's documented here:

此过程的逐步说明写在这里:

A walk-through of this process is written up here:

这里是一个使用Java脚本的人:

Here's one with a Javascript focus:

我可以保证它有效.生成提供了GArray必要细节的.typelib文件后,gi模块将为其提供熟悉的序列样式接口,因此您可以像使用列表一样使用它.

And I can vouch for the fact that it works. Once you generate a .typelib file providing the necessary details of your GArray, the gi module will provide a familiar sequence-style interface to it, so you can use it like a list.

不幸的是,您不能做的是使用gi框架公开您可能会从其他API获得的用于未指定GArray的函数!如果您尝试将这些GArray之一传递给函数,Python会抱怨它不是序列类型.

Unfortunately, what you cannot do is use the gi framework to expose functions for working with under-specified GArrays that you might get from other APIs! If you try to pass one of these GArrays into your function, Python complains about it not being a sequence type.

就我而言,我正在编写一个GStreamer应用程序,其中一个特定的管道元素正在生成包含几个GArray成员的GstMessage.虽然我无法编写访问器函数来直接读取这些成员的内容,但是我发现我可以编写使用GstStructure的函数,然后读取所需的成员并将其返回为gi可以用作a的完全指定的GArray.正确的Python顺序.

In my case, I was writing a GStreamer app, in which a particular pipeline element was generating GstMessages that contained a couple GArray members. While I couldn't write accessor functions to directly read the contents of these members, I found I could write functions which took the GstStructure, then read the desired member and returned it as a fully-specified GArray that gi could adapt as a proper Python sequence.

有关GArray的更多详细信息,请参见:

For more details on GArray, see:

  • https://developer.gnome.org/glib/stable/glib-Arrays.html
  • https://github.com/GNOME/glib/blob/master/glib/garray.h
  • https://github.com/GNOME/glib/blob/master/glib/garray.c

特别要注意的是,虽然garray.h将GArray定义为仅包含datalen成员的结构,但您可以在garray.c中看到此接口类型由struct _GRealArray支持,其中包含另外6个成员.

In particular, note that while garray.h defines a GArray as a struct containing only a data and len member, you can see in garray.c that this interface type is backed by struct _GRealArray, which contains an additional 6 members.

有关 GObject Introspection框架 Python gi模块的更多信息,请参见:

For further information about the GObject Introspection framework and the Python gi module, see:

  • https://gi.readthedocs.io/en/latest/
  • https://developer.gnome.org/gi/unstable/
  • https://pygobject.readthedocs.io/en/latest/

最后,PyGObject 可以为您无法控制的库启用解决方法的方法是将data成员公开为Python bytes对象,其长度等于.

Finally, what PyGObject could do to enable workarounds for libraries you don't control, is to expose the data member as a Python bytes object, with a length equal to GArray.len * GRealArray.elt_size.

这篇关于如何在Python中使用GLib.Array?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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