<h2>简介</h2>
<p>在这个答案中,我将尝试总结我在这个问题上所学到的知识,并提供一个解决方案来解决这个问题出现的一些情况。不幸的是,在某些情况下,似乎没有现成的解决方案,尽管我认为可以修改pythongi模块以启用解决方案(请参见下面<strong>结束思想</strong>)。在</p>
<h2>背景</h2>
<p>核心问题是<code>GArray</code>只是<code>malloc()</code>、<code>realloc()</code>和{<cd4>}的一个非常薄的包装。除此之外,它还添加了一些特性,比如ref计数和对零终止的内置支持。但是,<em>它缺少的一个显著特性是对数组元素类型的任何了解!</em>这意味着Python GI(GObject Introspection)模块无法调整任意的<code>GArray</code>作为Python序列类型,而没有关于{<cd1>}包含什么的进一步信息。在</p>
<h2>官方方法</h2>
<p>使用gi模块支持的<code>GArray</code>s的方法是生成一个.typelib文件,其中包含它需要的附加信息,以便适应每个特定的<code>GArray</code>实例。幸运的是,有一个工具链可以帮助您直接从源代码生成这些文件。在</p>
<p>要使用此方法,请首先根据此处定义的格式用注释块记录源代码:</p>
<ul>
<li><a href="https://wiki.gnome.org/Projects/GObjectIntrospection/Annotations" rel="nofollow noreferrer">https://wiki.gnome.org/Projects/GObjectIntrospection/Annotations</a></li>
</ul>
<p>接下来,运行g-ir-scanner工具,以生成一个.gir文件。此工具的文档可在以下位置找到:</p>
<ul>
<li><a href="https://gi.readthedocs.io/en/latest/tools/g-ir-scanner.html" rel="nofollow noreferrer">https://gi.readthedocs.io/en/latest/tools/g-ir-scanner.html</a></li>
</ul>
<p>最后,可以使用g-ir-compiler工具创建.typelib文件。记录如下:</p>
<ul>
<li><a href="https://gi.readthedocs.io/en/latest/tools/g-ir-compiler.html" rel="nofollow noreferrer">https://gi.readthedocs.io/en/latest/tools/g-ir-compiler.html</a></li>
</ul>
<p>此过程的详细介绍如下:</p>
<ul>
<li><a href="https://storageapis.wordpress.com/2014/07/25/minimalistic-example-of-the-glibs-gboxedtype-usage/" rel="nofollow noreferrer">https://storageapis.wordpress.com/2014/07/25/minimalistic-example-of-the-glibs-gboxedtype-usage/</a></li>
</ul>
<p>下面是一个重点关注Javascript的例子:</p>
<ul>
<li><a href="http://helgo.net/simon/introspection-tutorial/index.xhtml" rel="nofollow noreferrer">http://helgo.net/simon/introspection-tutorial/index.xhtml</a></li>
</ul>
<p>我可以保证它是有效的。一旦生成了一个.typelib文件,提供了<code>GArray</code>的必要细节,gi模块将为其提供一个熟悉的序列样式接口,因此您可以像使用列表一样使用它。在</p>
<h2>解决办法</h2>
<p>不幸的是,<strong>您不能做的是使用gi框架来公开在指定的garray下使用的函数,您可能会从其他api获得这些函数!如果您试图将这些<code>GArray</code>之一传递到函数中,Python会抱怨它不是序列类型。在</p>
<p>在我的例子中,我正在编写一个GStreamer应用程序,其中一个特定的pipeline元素正在生成<code>GstMessage</code>,其中包含一对<code>GArray</code>成员。虽然我无法编写访问器函数来直接读取这些成员的内容,但我发现我可以编写使用<code>GstStructure</code>的函数,然后读取所需的成员并将其作为一个完全指定的GArray返回,gi可以将其调整为一个适当的Python序列。在</p>
<h2>参考文献</h2>
<p>有关<code>GArray</code>的详细信息,请参阅:</p>
<ul>
<li><a href="https://developer.gnome.org/glib/stable/glib-Arrays.html" rel="nofollow noreferrer">https://developer.gnome.org/glib/stable/glib-Arrays.html</a></li>
<li><a href="https://github.com/GNOME/glib/blob/master/glib/garray.h" rel="nofollow noreferrer">https://github.com/GNOME/glib/blob/master/glib/garray.h</a></li>
<li><a href="https://github.com/GNOME/glib/blob/master/glib/garray.c" rel="nofollow noreferrer">https://github.com/GNOME/glib/blob/master/glib/garray.c</a></li>
</ul>
<p>特别要注意的是,虽然garray.h将<code>GArray</code>定义为只包含<code>data</code>和<code>len</code>成员的结构,但是在garray.c中可以看到这个接口类型是由<code>struct _GRealArray</code>支持的,它包含另外6个成员。在</p>
<p>有关<strong>GObject自省框架</strong>和Python gi模块的更多信息,请参见:</p>
<ul>
<li><a href="https://gi.readthedocs.io/en/latest/" rel="nofollow noreferrer">https://gi.readthedocs.io/en/latest/</a></li>
<li><a href="https://developer.gnome.org/gi/unstable/" rel="nofollow noreferrer">https://developer.gnome.org/gi/unstable/</a></li>
<li><a href="https://pygobject.readthedocs.io/en/latest/" rel="nofollow noreferrer">https://pygobject.readthedocs.io/en/latest/</a></li>
</ul>
<h2>结束语</h2>
<p>最后,PyGObject<em>可以为您不控制的库启用变通方法,就是将<code>data</code>成员公开为Python<code>bytes</code>对象,长度等于<code>GArray.len * GRealArray.elt_size</code>。在</p>