How to implement interface methods?

I’m an GObject newbie and have a doubt about implementing an interface:

In https://developer.gnome.org/gobject/stable/howto-interface-implement.html it looks like the implementation method uses “ViewerFile*”, i.e. the actual class, as type for self. This leads to a compilation error when the method is assigned, e.g. in “iface->save = viewer_file_editable_save;”, because iface->save() has “ViewerEditable*” as argument, while viewer_file_editable_save() has ViewerFile*.

On the other hand, in https://developer.gnome.org/gobject/stable/gtype-non-instantiable-classed.html it looks like the implementation method uses “ViewerEditable*”, i.e. the interface, as type for self. This solves the assignment problem, but now I’m not sure how to use viewer_file_editable_save() inside my class, where I have objects of type “ViewerFile*”, not “ViewerEditable*”.

I’m sure, I’m missing something, but what?

Many thanks in advance for any help!

I believe the example has an error in it. Basically your interface implementations are going to be passed the interface’s GType:

/* Signature of your override should be exactly the same as the interface */
static void
viewer_file_save (ViewerEditable *editable)
{
  /* Then cast the interface type passed in to the instance (implementor) type */
  ViewerFile *self = VIEWER_FILE (editable);

  /* Do stuff with #ViewerFile instance fields, etc */
}

So regardless of the GType of your implementing class, your overrides will always be passed the interface’s GType. Does that answer your question?

EDIT

Also, I think I missed the second part of your question. To call interface methods on your class, you would generally cast to ViewerEditable:

/* Assuming your have a pointer to the #ViewerFile */
ViewerFile *self = an_instance;

/* Cast it to the interface and call the interface method, which will lookup the
 * implementor's function */
viewer_editable_save (VIEWER_EDITABLE (self));
1 Like

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.