`
cloverprince
  • 浏览: 129462 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

GObject 09: An Interface

阅读更多
An interface is a class with multiple abstract methods.  A class may implement one or more interfaces which means that the class provides all the abstract methods specified in the interfaces.  This separates the behavior pattern from the actual implementation.

An interface cannot be instantiated.  However, if a class implements an interface, then the interface can be extracted from an instance of that class.

The full code to be ignored for now:
/* A subclass of GObject implementing a interface. */

#include <stdio.h>
#include <glib-object.h>

/* My Interface */
typedef struct myinterface myinterface_t;
struct myinterface {
    GTypeInterface something_as_boilerplate;

    void (*greet)(void *instance);
};

GType get_my_interface_typeid() {
    static my_type_id = 0;
    if(my_type_id==0) {
        GTypeInfo my_type_info = {
            sizeof(myinterface_t),  //class_size;

            NULL,               //base_init;
            NULL,               //base_finalize;

            /* classed types, instantiated types */
            NULL,               //class_init;
            NULL,               //class_finalize;
            NULL,               //class_data;

            /* instantiated types */
            0,                  //instance_size;
            0,                  //n_preallocs;
            NULL,               //instance_init;

            /* value handling */
            NULL,               //value_table;
        };

        my_type_id = g_type_register_static(
                G_TYPE_INTERFACE,
                "MyInterface",
                &my_type_info,
                0
                );
    }
    return my_type_id;
}

/* My Class */
typedef struct {
    GObject something_as_boilerplate;
    char* name;
} myinstance_t;

typedef struct {
    GObjectClass something_as_boilerplate;
} myclass_t;

void say_hello(myinstance_t *instance) { // a method of myinstance
    printf("Hello, %s!\n",instance->name);
}

void my_instance_init_func(myinstance_t *instance, gpointer data) {
    instance->name = "blahblah";
}

void my_class_init_func(myclass_t* klass, gpointer data) {
}

void init_my_interface_on_my_class(myinterface_t* iface, gpointer iface_data) {
    iface->greet = say_hello;
}

GType get_my_class_typeid() {
    static my_type_id = 0;
    if(my_type_id==0) {
        GTypeInfo my_type_info = {
            sizeof(myclass_t),  //class_size;

            NULL,               //base_init;
            NULL,               //base_finalize;

            /* classed types, instantiated types */
            (GClassInitFunc)my_class_init_func, //class_init;
            NULL,               //class_finalize;
            NULL,               //class_data;

            /* instantiated types */
            sizeof(myinstance_t),//instance_size;
            0,                  //n_preallocs;
            (GInstanceInitFunc)my_instance_init_func, //instance_init;

            /* value handling */
            NULL,               //value_table;
        };

        my_type_id = g_type_register_static(
                G_TYPE_OBJECT,
                "MyClass",
                &my_type_info,
                0
                );

        /* Add interface */

        GInterfaceInfo my_interface_info = {
            (GInterfaceInitFunc)init_my_interface_on_my_class, // interface_init
            NULL,   // interface_finalize
            NULL,   // interface_data
        };

        g_type_add_interface_static(
                my_type_id,
                get_my_interface_typeid(),
                &my_interface_info
                );
    }

    return my_type_id;
}


/* main function */

int main() {
    g_type_init();

    printf("Class type id: %d\n",get_my_class_typeid());
    printf("Class type name: %s\n",g_type_name(get_my_class_typeid()));
    printf("Interface type id: %d\n",get_my_interface_typeid());
    printf("Interface type name: %s\n",g_type_name(get_my_interface_typeid()));

    myinstance_t *instance = (myinstance_t*)g_object_new(
            get_my_class_typeid(),NULL);

    GObject *obj = g_object_new(g_object_get_type(),NULL);

    GObject *objs[2] = {instance,obj};

    int i;
    for(i=0;i<2;i++) {
        myinterface_t *iface = G_TYPE_INSTANCE_GET_INTERFACE(
                objs[i],get_my_interface_typeid(),myinterface_t);

        if(iface != NULL) {
            iface->greet(instance);
        } else {
            printf("This object does not implement myinterface.\n");
        }
    }

    return 0;
}


In GObject, you define an interface with a struct containing the abstract methods (represented by function pointers):
typedef struct myinterface myinterface_t;
struct myinterface {
    GTypeInterface something_as_boilerplate;

    void (*greet)(void *instance);
};


as well as the g_type_register_static function and specifys that it is a subclass of GInterface:
GType get_my_interface_typeid() {
    static my_type_id = 0;
    if(my_type_id==0) {
        GTypeInfo my_type_info = {
            sizeof(myinterface_t),  //class_size;

            NULL,               //base_init;
            NULL,               //base_finalize;

            /* classed types, instantiated types */
            NULL,               //class_init;
            NULL,               //class_finalize;
            NULL,               //class_data;

            /* instantiated types */
            0,                  //instance_size;
            0,                  //n_preallocs;
            NULL,               //instance_init;

            /* value handling */
            NULL,               //value_table;
        };

        my_type_id = g_type_register_static(
                G_TYPE_INTERFACE,
                "MyInterface",
                &my_type_info,
                0
                );
    }
    return my_type_id;
}


A class implements an interface using the g_type_add_interface_static function just after the class type is registered into the GObject library using g_type_register_static.  Note that only subclasses of the GObject class may implement interfaces.
        GInterfaceInfo my_interface_info = {
            (GInterfaceInitFunc)init_my_interface_on_my_class, // interface_init
            NULL,   // interface_finalize
            NULL,   // interface_data
        };

        g_type_add_interface_static(
                my_type_id,
                get_my_interface_typeid(),
                &my_interface_info
                );
    }


The init_my_interface_on_my_class function (that is a GInterfaceInitFunc) is important.  It specifies HOW a class implememts an interface.  Whenever a class is said to implement an interface, this function is called and a new instance of the interface class struct (that is, "struct myinterface" in this program) is created and passed into this function.  This function is supposed to override the abstract methods in this struct by providing the corresponding function pointers that overrides the abstract methods.
void init_my_interface_on_my_class(myinterface_t* iface, gpointer iface_data) {
    iface->greet = say_hello;
}



You can extract the interface class (struct myinterface) from an instance of myclass.  The macro G_TYPE_INSTANCE_GET_INTERFACE gets the specified interface struct fron an instance.
    myinstance_t *instance = (myinstance_t*)g_object_new(
            get_my_class_typeid(),NULL);

    GObject *obj = g_object_new(g_object_get_type(),NULL);

    GObject *objs[2] = {instance,obj};

    int i;
    for(i=0;i<2;i++) {
        myinterface_t *iface = G_TYPE_INSTANCE_GET_INTERFACE(
                objs[i],get_my_interface_typeid(),myinterface_t);

        if(iface != NULL) {
            iface->greet(instance);
        } else {
            printf("This object does not implement myinterface.\n");
        }
    }


Note that there is no compile-time type-checking on interface implementations.  You have to know what class implements what interface.  If a class does not implement the interface you specified, G_TYPE_INSTANCE_GET_INTERFACE will return NULL.

.NET languages like C# allows properties and events to appear in interfaces.  You can do these too in GObject by utilizing the base_init function in the GTypeInfo struct for the interface type.  However, as stated before, there is no compile-time type-checking on properties and signals.
分享到:
评论

相关推荐

    Giveda_GObject_c++11_v1.5

    *) GObject::connect函数;开发者使用本函数,将发射者的信号连接到接收者的槽函数。连接成功后,发射者发射信号,接收者的槽函数将会被调用。 *) GObject::disconnect函数;开发者使用本函数,将发射者的信号与接收...

    GObject Reference Manual

    GTypePlugin - An interface for dynamically loadable types GTypeModule - Type loading modules GObject - The base object type Enums and Flags - Enumeration and flags types GBoxed - A mechanism to ...

    gobject-snippets:UltiSnips C 片段有助于编写 GObject 代码

    UltiSnips C 片段有助于编写 GObject 代码 安装 这些片段使用 UltiSnips ( ) 所以你应该先安装和配置它。 我使用 Vundle ( ) 来管理 vim 插件,但这不是强制性的。 如果你使用 Vundle,你可以添加到你的 ~/.vimrc ...

    Gobject 离线API手册

    GObject是GTK+库的核心组件,它为C语言提供了一种面向对象的编程模型。在GTK+和Gnome开发中,GObject系统是构建复杂、可扩展软件的基础。这个离线API手册包含了GObject框架的详细信息,对于理解并利用GObject进行...

    Gobject Reference Manual

    接口通过GIInterface结构体表示,使用g_object_interface_install_property()和g_object_interface_add_signal()等函数来添加属性和信号。 3. 属性:GObject系统通过GParamSpec结构体管理属性,允许在运行时查询、...

    crystal-gobject:Crystal的gobject-introspection

    crystal-gobject:Crystal的gobject-introspection

    groonga-gobject:Groonga的GObject包装器

    Groonga GObject 描述 Groonga的GObject包装器。 去做... 安装 Debian GNU / Linux 。 运行以下命令: % sudo apt-get install -V -y gir1.2-groonga libgroonga-gobject0 的Ubuntu 。 运行以下命令: % ...

    Gobject 资料,全面介绍

    Gobject 资料,全面介绍Gobject 资料,全面介绍Gobject 资料,全面介绍Gobject 资料,全面介绍Gobject 资料,全面介绍Gobject 资料,全面介绍Gobject 资料,全面介绍

    gobject_setup_property_demo.zip

    4. **实现接口**:GObject系统允许你实现接口,这可以通过`G_IMPLEMENT_INTERFACE`宏来完成。在这个例子中,我们可能会看到如何重载GObject的实例接口和类接口。 5. **编写类初始化和实例初始化函数**:这些函数是...

    gobject:适用于PHP的静态Gobject绑定

    gtkforphp gobject扩展为GObject功能提供了语言绑定。 有关该库的文档和信息可以在找到 现在,这只不过是一个占位符。 您可以发送评论,补丁,问题 这仍然是实验性的扩展。 安装/配置 此扩展需要gtkforphp / glib...

    gobject_create_class_demo.tar.gz

    本示例用于演示GObject创建新类,类的继承与重载。代码实现了shape和square类,继承关系为: square -&gt; shape -&gt;gobject 其中,square重载了shape类的info接口。

    yard-gobject-introspection:YARD插件,用于从GObject Introspection数据检索文档

    码-对象反省码插件,用于基于GObject-Intropection构建库文档。要求Ruby / GObject-Introspection尝试一下 git clone ...

    cairo-gobject-1.15.12-3.el7.x86_64.rpm

    离线安装包,亲测可用

    python3-pygobject3:GObject库的Python 3绑定

    **Python3-pygobject3: GObject库的Python 3绑定** `python3-pygobject3` 是一个Python 3版本的绑定库,它允许Python程序员能够利用GObject库的功能,这是GNOME桌面环境的核心组件之一。GObject库是C语言编写的一个...

    lgi:使用GObject-Introspection将动态Lua绑定到GObject库

    液化天然气LGI是基于gobject内省的动态Lua绑定到基于GObject的库。 它允许直接从Lua使用基于GObject的库。 已获得许可的许可,请参见LICENSE文件全文。 该项目的主页位于。 LGI经过测试,并与标准Lua 5.1,Lua 5.2,...

    gir_ffi, 在运行时使用 FFI,为基于GObject的库自动生成绑定.zip

    gir_ffi, 在运行时使用 FFI,为基于GObject的库自动生成绑定 GirFFI由 Matijs van Zuijlen描述使用GObject内省存储库的GNOME的ruby 绑定。状态 特性为基于任何gobject的库创建绑定。在运行时生成绑定。为选定方法...

    python-gobject-3.22.0-1.el7_4.1.x86_64.rpm

    离线安装包,亲测可用

    gobject对象系统

    ### gobject对象系统详解 #### 一、简介 GObject是一种强大的对象系统,它为C语言提供了一套灵活且易于扩展的对象模型。虽然C语言本身不是面向对象的语言,但通过GObject,开发者能够构建出类似面向对象编程的功能...

    avahi-gobject-0.6.25-11.el6.i686.rpm

    avahi-gobject-0.6.25-11.el6.i686.rpm是centos工具包。

    gobject-2.0.dll

    gobject-2.0

Global site tag (gtag.js) - Google Analytics