Problemas en la API de C.

Es probable que encuentre algunos problemas en la biblioteca que está envolviendo, particularmente si es un proyecto nuevo. Aquí hay algunos problemas comunes, con soluciones.

G.6.1. No se pueden predeclarar estructuras

Por convenio, las estructuras se declaran en los encabezados de Glib/GTK+ igual que en:

typedef struct _ExampleWidget ExampleWidget;

struct _ExampleWidget
{
  ...
};

El «typedef» adicional le permite usar la estructura en una cabecera sin incluir su definición completa, simplemente predeclarándola repitiendo ese «typedef». Esto significa que no tiene que incluir la cabecera de la biblioteca de C en su cabecera de C++, por lo tanto la dejará fuera de su API pública. gmmproc asume que se usó esta técnica, por lo que verá errores de compilación si ese no es el caso.

Este error del compilador podría tener este aspecto:

example-widget.h:56: error: using typedef-name 'ExampleWidget' after 'struct'
../../libexample/libexamplemm/example-widget.h:34: error: 'ExampleWidget' has a previous declaration here
make[4]: *** [example-widget.lo] Error 1
o este:
example-widget.h:60: error: '_ExampleWidget ExampleWidget' redeclared as different kind of symbol
../../libexample/libexamplemm/example-widget.h:34: error: previous declaration of 'typedef struct _ExampleWidget ExampleWidget'

Esto es fácil de corregir en la biblioteca de C, así que envíe un parche al mantenedor pertinentes.

G.6.2. Falta de propiedades

Por convenio, los objetos de glib/GTK+ tienen funciones *_new(), como example_widget_new() que no hacen más que llamar a g_object_new() y devolver el resultado. Los parámetros de entrada se proporcionan a g_object_new() junto con los nombres de las propiedades a las que se asignan. Por ejemplo,

GtkWidget* example_widget_new(int something, const char* thing)
{
        return g_object_new (EXAMPLE_TYPE_WIDGET, "something", something, "thing", thing, NULL);
}

Esto le permite a los enlaces entre lenguajes implementar sus propios equivalentes (como los constructores de C++), sin usar la función *_new(). Esto a menudo es necesario para poder instanciar realmente un GType derivado, para añadir sus propios ganchos para manejadores de señales y «vfuncs».

Como mínimo, la función _new() no debe usar ninguna API privada (funciones que sólo están en un archivo .c). Incluso cuando no hay funciones, a veces se pueden reimplementar 2 ó 3 líneas de código en una función _new() siempre que esas líneas de código usen una API que esté disponible.

Otra solución es añadir una función *_construct() que el constructor de C++ pueda llamar después de haber instanciado su propio tipo. Por ejemplo,

GtkWidget* example_widget_new(int something, const char* thing)
{
        ExampleWidget* widget;
        widget = g_object_new (EXAMPLE_TYPE_WIDGET, NULL);
        example_widget_construct(widget, "something", something, "thing", thing);
}

void example_widget_construct(ExampleWidget* widget, int something, const char* thing)
{
        //Do stuff that uses private API:
        widget->priv->thing = thing;
        do_something(something);
}

Incorporar propiedades, y asegurar que interactúan con otras propiedades correctamente, es relativamente difícil de corregir en la biblioteca de C, pero es posible, por lo que rellene un informe de error e intente enviar un parche al mantenedor correspondiente.