如何从Python中的GLib.GString获取原始字节?

时间:2015-03-23 15:49:49

标签: python glib pygobject gobject-introspection

我有一个使用GTK3通过GObject内省(Python 2.7和PyGObject 3.14)用Python编写的应用程序。我正在尝试使用WebKit加载网页并访问它加载的所有资源的内容。我可以通过连接到我用来加载页面的WebKitWebView对象的resource-load-finished信号来实现这一点。

在我的信号处理程序中,我使用web_resource参数中的WebKitWebResource对象来访问加载的数据。当get_data()不包含NULL字节时,从get_data()返回的GLib.GString一切正常,我可以使用data.str访问我需要的东西。但是,当数据确实包含NULL字节时(通常是加载资源的MIME类型是图像时),data.len是正确的,但data.str只包含直到第一个NULL字节的数据。我可以通过调用data.free_to_bytes()来访问原始字节,这会返回一个GLib.GBytes实例,但是当信号处理程序返回应用程序段错误时。我正在尝试访问已加载资源中的所有数据。

我希望以下代码有助于演示此问题。

from gi.repository import Gtk
from gi.repository import WebKit

def signal_resource_load_finished(webview, frame, resource):
    gstring = resource.get_data()
    print(resource.get_mime_type())
    desired_len = gstring.len
    # gstring.str is missing data because it returns the data up to the first NULL byte
    assert(gstring.str == desired_len) # this assertion fails

    # calling this causes a segfault after the handler returns, but the data is accessible from gbytes.get_data()
    #gbytes = gstring.free_to_bytes()
    #assert(len(gbytes.get_data()) == desired_len) # this assertion succeeds before the segfault
    return

webview = WebKit.WebView()
webview.connect('resource-load-finished', signal_resource_load_finished)
webview.connect('load-finished', Gtk.main_quit)
# lol cat for demo purposes of a resource containing NULL bytes (mime type: image/png)
webview.load_uri('http://images5.fanpop.com/image/photos/30600000/-Magical-Kitty-lol-cats-30656645-1280-800.png')
Gtk.main()

1 个答案:

答案 0 :(得分:2)

你不想使用free_to_bytes因为这不仅会给你你想要的字节,而且还会在没有Python知道的情况下从内存中释放字符串 - 正如你所发现的那样,它会崩溃你的程序。不幸的是,没有相应的get_bytes方法,因为GLib.String并非真正用于保存二进制数据。

事实上,我认为WebKit API中的一个错误是资源有效负载仅作为GLib.String提供。他们似乎已经在WebKit2中纠正了这个错误:http://webkitgtk.org/reference/webkit2gtk/stable/WebKitWebResource.html

如果可以,请考虑切换到WebKit2(from gi.repository import WebKit2)。