Sharing the private instance across multiple source files

I have an implementation of a gtkwidget subclass and I decided to tighten the source file by separating it into multiple header/source files. However, many functions take advantage of the private instance using the generated gtk_x_get_instance_private() and I would like to keep it that way. How can I use this function in those new source files?

Of course, I should start defining (or forwarding) the instance private structure in the header, or redefining it in sources, then what?

One way would be to put the private structure definition in a mywidget-private.h that you should make sure does not appear in your public headers

Sure, but then I’d have to prototype get_instance_private() function. What does the the G_ADD_PRIVATE expand to? It’s giving me conflicting types

You can always add a MyWidgetPrivate *priv member to your class definition like in the olden days and populate it on init with my_widget_get_instance_private()

I could cache it yes, but that would require me changing a lot of code. As I said, I’d prefer to keep it that way, as it is now, with all the get_instance_private() functions, if possible.

You cannot use the generated get_instance_private() function across compilation boundaries, because it’s a static inline that accesses global static data (the offset of the private data in the overall instance allocation).

If you want to access the private data in different files, you will need to keep a priv pointer.

Alternatively, and more appropriately, you could:

  • add accessor functions for the data you want to access and keep them to a private header
  • declare the type as final, and put the private data into the instance structure, then put the instance structure in a private header

The former lets you subclass the type, while the latter does not.

1 Like

Surely I could create the function manually though, reimplement the macro.

The get_instance_private() is not a macro, and it’s not added by G_ADD_PRIVATE. The whole instance private data handling is generated by G_DEFINE_TYPE_EXTENDED, which is what G_DEFINE_TYPE calls. G_ADD_PRIVATE only tells GType to reserve the size of the instance private data when creating an instance.

The same G_DEFINE_TYPE_EXTENDED macro defines the static, global variable that contains the offset for the instance private data from the instance pointer; you cannot access that from outside the compilation unit, and you cannot expose the static inline function.

Of course, you could reimplement this whole machinery by yourself: you just need to do what G_DEFINE_TYPE_EXTENDED does. It’s all public API, anyway. Nevertheless, what you want to achieve is simply not possible within the constraints of the code generated by the GObject macros—and it’s not possible for a reason.

My strong suggestion is to not give out the whole instance private data across compilation unit; use specific accessor functions for the data you need; it’ll make refactoring easier, and it’ll keep your code cleaner.

1 Like

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