【问题标题】:gobject overwrite property in derived classgobject 覆盖派生类中的属性
【发布时间】:2021-08-31 03:37:49
【问题描述】:

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

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

现在我正在尝试制作一个 GObject 样式的 EdfFile、EdfHeader 和 EdfSignal 类。 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
            );
}

我尝试覆盖派生类 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 保释! GLib-GObject-FATAL-WARNING:值 'gint' 类型的“-8388608”无效或超出属性范围 'gint' 类型的'digital-min'

(/home/maarten/github/eeg-fft/debug/test/unittest:7085): GLib-GObject-WARNING **:11:22:30.745:'gint'类型的值“-8388608” 'gint' 类型的属性 'digital-min' 无效或超出范围

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

【问题讨论】:

    标签: c glib gobject


    【解决方案1】:

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

    覆盖属性不允许您更改用于验证属性值的最大值/最小值,看起来您正在尝试这样做。如果你这样做,它会破坏类型系统:如果你有一个变量是EdfBdfSignal 的实例,但它正在被一些通用代码处理为EdfSignal,那么该通用代码应该期望接收如果它获得digital-max 的值(例如),则为 16 位值。但它最终可能会收到大于 16 位的值。

    如果不知道其余代码的结构,我无法自信地提出解决方案。我会考虑:

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

    【讨论】:

    • 您好菲利普,感谢您的回答!我确实在尝试更改派生类中参数的验证。所以也许我必须放宽对最小值和最大值的限制。采用并行方法将是不幸的,因为 +/- 90% 的代码我可以很高兴地从基类 EdfSignalClass 派生,所以第二种方法会复制相当多的代码。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-07-05
    • 1970-01-01
    • 2012-06-02
    • 2013-06-25
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多