Signals with gchar** arguments

It happens that you want a signal having pointers to strings (gchar**)
as argument. Those arguments are used to retrieve strings in the signal
handler, and return them to the signal emitter. A prominent real-world
example is the "authenticate" signal of SoupSession[1]:

    static void
    authenticate (SoupSession  *session, 
                  /* other arguments... */
                  gchar       **username,
                  gchar       **password,
                  gpointer      user_data)
      /* ... */

      g_free (*username);
      *username = g_strdup (lookup_username ());

      /* ... */

Notice that this use of "gchar**" arguments is different from the usage
as "NULL terminated arrays of strings", aka. "G_TYPE_STRV".

Currently glib doesn't provide a fundamental type for dealing with that
kind of arguments, so usually G_TYPE_POINTER is used as argument for the
g_signal_new call registering such signals. Technically this works, but
it leads to bad API documentation. The signal argument is documented as
"gpointer" whilst being in fact of the type "gchar**", which is quite a

So my question is: How to solve this issue? 

  - Introduce a new fundamental type "G_TYPE_STRING_PTR" duplicating 
    the behaviour of "G_TYPE_POINTER" under a new name.
  - Patch gtk-doc to retrieve the real argument by inspecting for
    instance the signature of the signal's virtual method?

Currently I use the approach of registering an artificial fundamental
type of the name EpcStringPtr to get proper documentation in libepc:

epc_string_ptr_get_type (void)
  static GType type = G_TYPE_INVALID;

  if (!type)
      static GTypeInfo info = {
        0,                    /* class_size */
        NULL,                 /* base_init */
        NULL,                 /* base_finalize */
        NULL,                 /* class_init */
        NULL,                 /* class_finalize */
        NULL,                 /* class_data */
        0,                    /* instance_size */
        0,                    /* n_preallocs */
        NULL,                 /* instance_init */
        NULL                  /* value_table */

      static GTypeFundamentalInfo fundamental_info = {

      info.value_table = g_type_value_table_peek (G_TYPE_POINTER);
      g_assert (NULL != info.value_table);

      type = g_type_register_fundamental (g_type_fundamental_next (),
                                          &info, &fundamental_info, 0);

  return type;

It fulfills my needs of documenting the argument type, but my feeling is
there should be a better solution for this problem. Feels like shooting
birds with cannons ("to break a butterfly on a wheel"?).


Mathias Hasselmann <mathias hasselmann gmx de>

Attachment: signature.asc
Description: Dies ist ein digital signierter Nachrichtenteil

[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]