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