如何在 Gio.Settings 中获取可重定位模式的路径?

Posted

技术标签:

【中文标题】如何在 Gio.Settings 中获取可重定位模式的路径?【英文标题】:How to get paths for relocatable schemas in Gio.Settings? 【发布时间】:2015-08-21 15:49:07 【问题描述】:

在 Gio.Settings 中,我可以使用列出可重定位架构

Gio.Settings.list_relocatable_schemas()

我可以使用

Gio.Settings.new_with_path(schema_id, path)

获取Gio.Settings 实例。但是我怎样才能获得当前用于给定schema_idpath 的所有值?

【问题讨论】:

【参考方案1】:

通常,模式具有确定路径的固定路径 设置存储在概念性全局设置树中。 然而,模式也可以是“可重定位的”,即不配备 固定路径。这很有用,例如当架构描述一个 'account',并且您希望能够存储任意数量的 帐户。

new_with_path 不就是为了这个吗?您必须将架构存储在与帐户关联的某个位置,但这不是设置系统的责任。我认为new_with_path 适用于您的架构依赖于帐户的情况。

我认为您可以通过 GSettingsSchemas 找到更多信息 - 这是描述中的一个示例,说明 Schema 是插件的一部分。

【讨论】:

【参考方案2】:

很遗憾,您无法通过 Gio.Settings 执行此操作。

我在这里看到两个选项:

保留单独的 gsetting 以存储可重定位架构的路径

利用dconf API,这是一个低级配置系统。由于没有 Python 绑定(猜测是 Python 问题),我建议使用 ctypes 与 C 绑定。 如果您知道可重定位架构的根路径,您可以使用下面的 sn-p 列出它们。

import ctypes
from ctypes import Structure, POINTER, byref, c_char_p,  c_int, util

from typing import List


class DconfClient:
    def __init__(self):
        self.__dconf_client = _DCONF_LIB.dconf_client_new()

    def list(self, directory: str) -> List[str]:
        length_c = c_int()
        directory_p = c_char_p(directory.encode())
        result_list_c = _DCONF_LIB.dconf_client_list(self.__dconf_client, directory_p, byref(length_c))

        result_list = self.__decode_list(result_list_c, length_c.value)
        return result_list

    def __decode_list(self, list_to_decode_c, length):
        new_list = []
        for i in range(length):
            # convert to str and remove slash at the end
            decoded_str = list_to_decode_c[i].decode().rstrip("/")
            new_list.append(decoded_str)
        return new_list


class _DConfClient(Structure):
    _fields_ = []


_DCONF_LIB = ctypes.CDLL(util.find_library("dconf"))
_DCONF_LIB.dconf_client_new.argtypes = []
_DCONF_LIB.dconf_client_new.restype = POINTER(_DConfClient)
_DCONF_LIB.dconf_client_new.argtypes = []
_DCONF_LIB.dconf_client_list.argtypes = [POINTER(_DConfClient), c_char_p, POINTER(c_int)]
_DCONF_LIB.dconf_client_list.restype = POINTER(c_char_p)

【讨论】:

【参考方案3】:

不能,至少对于任意架构而言,这是根据定义可重定位架构是:可以有多个实例的架构,存储在多个任意路径中。

由于可重定位模式实例基本上可以存储在 DConf 内任何地方gsettings 无法列出它们的路径,它不会跟踪实例。 dconf 也帮不了你,因为它根本没有 schemas 的概念,它只知道路径和键。它可以列出给定路径的子路径,仅此而已。

应用程序在创建给定可重定位架构的多个实例时,应将每个实例存储在合理且易于发现的路径中,例如(不可重定位的)应用程序架构的子路径。或者将实例路径(或后缀)作为列表键存储在此类架构中。

或两者兼有,就像 Gnome 终端对其配置文件所做的那样:

org.gnome.Terminal.ProfilesList 是一个不可重定位的常规模式,存储在 DConf 路径 /org/gnome/terminal/legacy/profiles:/ 该架构有 2 个键,一个带有单个 UUID 的 default 字符串,以及一个包含 UUID 的 list 字符串列表。 每个配置文件都是 relocatable 架构 org.gnome.Terminal.Legacy.Profile 的一个实例,并且存储在您猜想.../org/gnome/terminal/legacy/profiles:/:<UUID>/

这样,客户端可以使用gsettings 访问所有实例,读取list 并从UUID 构建路径,或者从dconf 直接列出/org/gnome/terminal/legacy/profiles:/ 的子路径。

当然,对于 non-relocatable 架构,您始终可以通过以下方式获取它们的路径:

gsettings list-schemas --print-paths

【讨论】:

以上是关于如何在 Gio.Settings 中获取可重定位模式的路径?的主要内容,如果未能解决你的问题,请参考以下文章

Linux下驱动模块学习

操作数必须是可重定位的程序集 x86 问题

现代多数实用编译程序所产生的目标代码都是一种可重定位的指令代码,在运行前必须借助于一个

北斗GPS双模定位两点的间距如何求???急急急。。。

可重定位文件结构分析

目标文件