十一、Gio Resource

struct GResource {
  /* No available fields */
}

应用程序applications和库libraries通常包含二进制或文本数据,这些数据实际上是应用程序的一部分,而不是用户数据。例如GtkBuilder .ui文件,splashscreen图像,GMenu标记XML, CSS文件,图标等。它们通常以文件的形式存储在$datadir/appname中,或者以字符串字面量的形式手动包含在代码中。

GResource API[glib-compile-resources]。[glib-compile-resources]程序提供了一个方便高效的替代方案,它有一些很好的属性。你可以像普通文件一样维护这些文件,所以很容易编辑它们,但是在构建过程中,这些文件会被组合成一个链接到可执行文件中的二进制包。这意味着加载资源文件是高效的(因为它们已经在内存中,与其他实例共享)和简单的(不需要检查I/O错误或在文件系统中定位文件)。它还使创建可重定位的应用程序变得更容易。

资源文件也可以标记为压缩文件compressed。这些文件将以压缩形式包含在资源包中,但在使用资源时将自动解除压缩。这非常有用,例如,对于只解析一次(或很少解析)然后丢弃的大型文本文件(调用次数少)。

通过将preprocess属性的值设置为逗号分隔的预处理选项列表,也可以将资源文件标记为可预处理。目前唯一支持的选项是:

xml-stripblanks它将使用xmllint命令从XML文件中去除可忽略的空白。为此,必须将XMLLINT环境变量设置为XMLLINT可执行文件的完整路径,或者必须将XMLLINT包含在该路径中;否则跳过预处理步骤。

to-pixdata(自gdk-pixbuf 2.32起已弃用),它将使用gdk-pixbuf-pixdata命令将图像转换为GdkPixdata格式,这允许您直接使用资源文件中的数据创建pixbufs,而不是它的(未压缩)副本。为此,路径中必须有gdk-pixbuf-pixdata程序,或者必须将GDK_PIXBUF_PIXDATA环境变量设置为gdk-pixbuf-pixdata可执行文件的完整路径;否则资源编译器将中止。自从gdk-pixbuf 2.32以来,to-pixdata已经被弃用,因为GResource同样支持嵌入现代图像格式。与其直接使用它**,不如在GResource中嵌入PNG或SVG文件**。

json-stripblanks将使用json-glib-format命令从JSON文件中删除可忽略的空格。要做到这一点,必须将环境变量JSON_GLIB_FORMAT设置为json-glib-format可执行文件的完整路径,或者它必须在该路径中;否则跳过预处理步骤。此外,至少需要1.6版本的json-glib格式。

使用给定的前缀和file元素中的文件名的组合,资源文件将在GResource命名空间中导出。alias属性可用于更改文件名,以便在资源命名空间中的不同位置公开它们。通常,这用于包含来自不同源目录的文件,而不会暴露资源命名空间中的源目录,如下面的示例所示。

资源包是由[glib-compile-resources].[glib-compile-resources]程序创建的,该程序接受一个描述资源包的XML文件和XML引用的一组文件。这些组合成二进制资源包。

资源描述示例:注意前缀开始时候有斜杠,结尾没有。调用资源的时候/org/gtk/Example/file_name

<?xml version="1.0" encoding="UTF-8"?>
<gresources>
  <gresource prefix="/org/gtk/Example">
    <file>data/splashscreen.png</file>
    <file compressed="true">dialog.ui</file>
    <file preprocess="xml-stripblanks">menumarkup.xml</file>
    <file alias="example.css">data/example.css</file>
  </gresource>
</gresources>

这将创建一个包含以下文件的资源包:

/org/gtk/Example/data/splashscreen.png
/org/gtk/Example/dialog.ui
/org/gtk/Example/menumarkup.xml
/org/gtk/Example/example.css

请注意,进程中的所有资源都共享相同的命名空间,因此请使用java风格的路径前缀(如上例所示)来避免冲突。

然后,您可以使用[glib-compile-resources][glib-compile-resources]将XML编译为可以用g_resource_load()加载的二进制包。然而,更常见的是使用-generate-source和-generate-header参数来创建直接链接到应用程序的源文件和头文件。这将生成get_resource()、register_resource()和unregister_resource()函数,以传递给[glib-compile-resources]``[glib-compile-resources]的–c-name参数作为前缀。get_resource()返回生成的GResource对象register和unregister函数注册资源,以便可以使用g_resources_lookup_data()访问其文件。

一旦创建并注册了GResource,就可以在进程中使用API调用(如g_resources_open_stream())来访问数据流或g_resources_lookup_data()来获得数据的直接指针,从而全局访问其中的所有数据。你也可以使用类似于" resource:///org/gtk/Example/data/splashscreen.png "的uri来访问GFile中的资源数据。

一些高级api,如GtkApplication,将自动从资源命名空间中的某些知名路径加载资源,以方便使用。有关这些api的详细信息,请参阅文档。

生成的源代码有两种形式,默认版本使用编译器对构造函数和析构函数的支持(如果可用),在启动或库加载时自动创建和注册GResource。如果传递--manual-register参数,则会创建两个用于注册/注销资源的函数。这需要在应用程序/库中显式地调用初始化,但它在所有平台上都可以工作,即使是在不支持构造函数的次要平台上。(至少Win32、Mac OS和Linux支持构造函数。)

请注意,资源数据可以直接指向数据段(例如library),所以如果你在运行时卸载库,你需要非常小心地保存来自资源的数据指针,因为当库卸载时,这将消失。然而,在实践中这通常不是问题,因为大多数资源访问都是为了您自己的资源,而且资源数据通常只在解析期间使用一次,然后发布。

在调试程序或测试对已安装版本的更改时,能够在不重新编译的情况下替换程序或库中的资源,以达到调试或快速破解和测试的目的,通常很有用。从GLib 2.50开始,就可以使用G_RESOURCE_OVERLAYS环境变量有选择地覆盖文件系统中的资源。它是一个由g_searchpath_separator分隔的替换列表,在资源查找期间执行。在setuid进程中运行时,它会被忽略。

代换有这样的形式

/org/gtk/libgtk=/home/desrt/gtk-overlay

=之前的部分是覆盖应用的资源子路径。后面的部分是一个文件系统路径,其中包含了你希望作为资源加载的文件和子目录,具有相同的名称。

在上面的例子中,如果应用程序试图加载资源路径为/org/gtk/libgtk/ui/gtkdialog的资源。然后GResource会检查文件系统路径/home/desrt/gtk-overlay/ui/gtkdialog.ui。如果在那里找到了文件,就会使用它。这是一个覆盖层,而不是完全的替换,这意味着如果在该路径下没有找到文件,则将使用内置版本。目前不支持whiteouts。

替换必须以斜杠开始,并且不能在=之前包含一个斜杠。理想情况下,斜杠后面的路径应该是绝对的,但这不是严格要求的。可以用单个文件覆盖单个资源的位置。

可用版本:2.32

参考:Gio Resource

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值