gobject 在派生 class 中覆盖 属性

gobject overwrite property in derived class

我正在尝试读取 EDF 格式的文件。 EDF 格式相当古老(1990 年代)。它存在一个header的ASCII格式和大量来自不同传感器的样本;想想脑电图、心电图或其他类型的电极,其样本被转换为数字值。每个换能器称为一个信号。 EDF 样本以 little endian 2s 补充 16 位样本的形式出现。文件的 header 将说明存在哪些信号以及它们如何出现。

然而随着时间的推移,EDF 的一种方言被设计出来,称为 BDF,它在很大程度上与 EDF 相同,但它可以包含类似于 EDF 但具有 24 位精度的样本。

现在我正在尝试制作 GObject 样式的 EdfFile、EdfHeader 和 EdfSignal class。 BDF 等价物是 EdfBdfFile、EdfBdfHeader 和 EdfBdfSigal。所有 BDF 文件都源自那里的 Edf 等价物。

EdfSignal 有两个我想在 EdfBdfSignal 中覆盖的属性,即 "digital-min""digital-max"

我正在尝试按如下方式执行此操作:

edf-signal.c:

static void
edf_signal_class_init(EdfSignalClass* klass)
{
    GObjectClass* object_class = G_OBJECT_CLASS(klass);

    object_class->set_property = edf_signal_set_property;
    object_class->get_property = edf_signal_get_property;
    object_class->dispose = edf_signal_dispose;
    object_class->finalize = edf_signal_finalize;

    klass->append_new_record = append_new_record;

    // A number of other properties here

    edf_signal_properties [PROP_DIGITAL_MIN] = g_param_spec_int(
            "digital-min",
            "digital-minimum",
            "The digital minimum of an signal",
            G_MININT16,
            G_MAXINT16,
            0,
            G_PARAM_READWRITE
            );

    edf_signal_properties [PROP_DIGITAL_MAX] = g_param_spec_int(
            "digital-max",
            "digital-maximum",
            "The digital maximum of an signal",
            G_MININT16,
            G_MAXINT16,
            0,
            G_PARAM_READWRITE
            );
    // Some more properties here.

    g_object_class_install_properties(
            object_class, N_PROPERTIES, edf_signal_properties
            );
}

并且我尝试在导出 class edf-bdf-signal.c:

中覆盖属性
static void
edf_bdf_signal_class_init(EdfBdfSignalClass* klass)
{
    GObjectClass* object_class = G_OBJECT_CLASS(klass);
    object_class->set_property = set_property;
    object_class->get_property = get_property;
    EdfSignalClass* signal_class = EDF_SIGNAL_CLASS(klass);

    signal_class->append_new_record = append_new_record;

    // I would like to name these properties "digital-max" and
    // "digital-min" as well, but the gobject type system
    // doesn't like that.

    obj_properties[PROP_DIGITAL_MAX] = g_param_spec_int(
        "bdf-digital-max",
        "Digital-Max",
        "The digital maximum of a BdfFile.",
        -8388608,
        8388607,
        0,
        G_PARAM_READWRITE | G_PARAM_CONSTRUCT
        );

    obj_properties[PROP_DIGITAL_MIN] = g_param_spec_int(
        "bdf-digital-min",
        "Digital-Min",
        "The digital minimum of a BdfFile.",
        -8388608,
        8388607,
        0,
        G_PARAM_READWRITE | G_PARAM_CONSTRUCT
    );

    g_object_class_override_property(object_class, PROP_DIGITAL_MAX, "digital-max");
    g_object_class_override_property(object_class, PROP_DIGITAL_MIN, "digital-min");

    g_object_class_install_properties(object_class, N_PROPERTIES, obj_properties);

}

如果我现在正在读取 BDF 文件,我会遇到以下错误:

ok 1 /BdfFile/create Bail out! GLib-GObject-FATAL-WARNING: value "-8388608" of type 'gint' is invalid or out of range for property 'digital-min' of type 'gint'

(/home/maarten/github/eeg-fft/debug/test/unittest:7085): GLib-GObject-WARNING **: 11:22:30.745: value "-8388608" of type 'gint' is invalid or out of range for property 'digital-min' of type 'gint'

这告诉我我没有成功覆盖 属性。因为 -8388608 在 EdfBdfSignal 中应该有效,但在 EdfSignal 中无效。我希望知道是否可以这样做。

您不需要 edf_bdf_signal_class_init() 中的 g_param_spec_int() 调用来覆盖属性 — 您只需要 g_object_class_override_property() 调用。

覆盖属性不允许您更改用于验证 属性 值的 maximum/minimum,您似乎正试图这样做。如果你这样做,它会破坏类型系统:如果你有一个变量,它是 EdfBdfSignal 的一个实例,但它被一些泛型代码作为 EdfSignal 处理,那个泛型代码如果它得到 digital-max 的值(例如),它应该期望收到一个 16 位的值。不过,它最终可能会收到一个大于 16 位的值。

在不了解您其余代码的结构的情况下,我无法自信地为此提出解决方案。我会考虑:

  • 放宽 EdfSignaldigital-maxdigital-min 的 minimum/maximum 值,以便它们可以容纳 EdfBdfSignal 使用的值。您可能会添加一个额外的只读 属性,它给出 digital-max/digital-min 的位宽:EdfSignal 的值为 16,EdfSignal 的值为 24 EdfBdfSignal.
  • EdfBdfSignal 更改为不派生自 EdfSignal,而是并行实现。 类 都将实现通用功能的接口,但该接口不会定义 digital-min/digital-max 属性。这些属性的实现和范围可以在 EdfSignalEdfBdfSignal.
  • 中独立