结构体
线程库Resource
自:2.32
描述 [源]
struct GResource {
/* No available fields */
}
应用程序和库通常包含二进制或文本数据,这些数据实际上是应用程序的一部分,而不是用户数据。例如 GtkBuilder
.ui
文件、启动画面图像、GMenu
标记 XML、CSS 文件、图标等。这些通常作为 $datadir/appname
中的文件提供,或者手动作为字符串直接包含在代码中。
GResource
API 和 glib-compile-resources
程序提供了对此的便捷且高效的替代方案,具有一定的优点。您像处理普通文件一样维护这些文件,因此很容易编辑它们,但在构建过程中将这些文件组合成一个二进制包,并将其链接到可执行文件中。这意味着加载资源文件非常高效(因为它们已经存在于内存中,与其他实例共享),且非常简单(无需检查像I/O错误或在文件系统中定位文件)。这也使得创建可移动应用程序变得更加容易。
资源文件也可以被标记为压缩。这样的文件将以压缩形式包含在资源包中,但在使用资源时将被自动解压缩。这对于例如一次(或很少)解析然后丢弃的大文本文件非常有用。
资源文件还可以通过将 preprocess
属性的值设置为预处理选项的逗号分隔列表来标记为预处理的。目前唯一支持的选项是
-
xml-stripblanks
,它将使用xmllint
命令从 XML 文件中删除可忽略的空白。为此,必须将XMLLINT
环境变量设置为 xmllint 可执行文件的完整路径,或者xmllint必须位于PATH
中;否则,将跳过预处理步骤。 -
to-pixdata
(自 gdk-pixbuf 2.32 以来已废弃)将使用gdk-pixbuf-pixdata
命令将图像转换为GdkPixdata
格式,这使得您可以使用资源文件内部的数据直接创建 pixbufs,而无需它的(未压缩)副本。为此,必须将gdk-pixbuf-pixdata
程序放在PATH
中,或必须将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
可执行文件的完整路径,或者它必须位于PATH
中;否则将跳过预处理步骤。此外,至少需要json-glib-format
的 1.6 版本。
资源文件将以 GResource
命名空间的形式导出,使用给定的 prefix
和 file
元素中的文件名进行组合。可以使用 alias
属性更改文件名,以便在资源命名空间的不同位置暴露它们。通常,这用于包含来自不同源目录的文件,而不在资源命名空间中暴露源目录,如以下示例所示。
资源包是由 glib-compile-resources
程序创建的,它接受描述包的 XML 文件和 XML 引用的文件集。这些被组合成一个二进制资源包。
示例资源描述
<?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
将 XML 编译成二进制包,您可以使用 g_resource_load()
加载它。但是,更常见的是使用 --generate-source
和 --generate-header
参数来创建一个源文件和头文件,以将它们直接链接到您的应用程序。这将为 get_resource()
、register_resource()
和 unregister_resource()
函数生成,前面带的是传递给 glib-compile-resources
的 --c-name
参数。 get_resource()
返回生成的 GResource
对象。注册和注销函数将资源注册以便使用 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 上可用。)
请注意,资源数据可以直接指向例如库的数据段,因此如果您在运行时卸载库,则需要非常小心地保持资源中的数据指针,因为这将随着库的卸载而消失。然而,在实际应用中,这通常不是问题,因为大多数资源访问都是针对您自己的资源,并且资源数据通常在一开始(解析时)使用一次,然后释放。
覆盖(Overlays)
在调试程序或测试已安装版本的更改时,往往有用处能够代替程序或库中的资源,而无需重新编译,以便于调试或快速修改和测试。自 GLib 2.50 开始,可以使用 G_RESOURCE_OVERLAYS
环境变量选择性地使用文件系统的替换资源覆盖资源。它是一个在资源查找期间执行的替换的 G_SEARCHPATH_SEPARATOR
分隔列表。当在 setuid 进程中运行时,将忽略它。
替换的形式为
/org/gtk/libgtk=/home/desrt/gtk-overlay
=
之前的部分是应用覆盖的资源子路径。之后的部分是文件系统路径,其中包含您希望按等效名称加载为资源的文件和子目录。
在上面的示例中,如果应用程序尝试加载资源路径为 /org/gtk/libgtk/ui/gtkdialog.ui
的资源,那么 GResource
会检查文件系统路径 /home/desrt/gtk-overlay/ui/gtkdialog.ui
。如果在该路径下找到一个文件,则会使用该文件。这是一个覆盖,而不是完全替换,这意味着如果在该路径下找不到文件,将使用内置版本。目前不支持清空。
替换必须以斜杠开头,且在 =
前不允许有结尾斜杠。斜杠后面的路径理想情况下应该是绝对路径,但这不是严格要求的。可以覆盖单个资源的路径为单独的文件。
自 2.32 版本以来可用