Problémy v API v C

Nejspíše se setkáte s některými problémy v knihovně, kterou balíte, zejména pokud jde o nový projekt. Zde jsou některé běžné problémy včetně řešení.

G.6.1. Nejde předeklarovat struktury

By convention, structs are declared in glib/GTK-style headers like so:

typedef struct _ExampleWidget ExampleWidget;

struct _ExampleWidget
{
  …
};

Doplňující typedef umožňuje použít strukturu v hlavičkovém souboru bez vložení její plné definice, pouze jejím předeklarováním pomocí zopakování tohoto typedef. To znamená, že nemusíte vkládat hlavičkový soubor knihovny v C do svého hlavičkového souboru v C++ a tím ji udržet mimo veřejné API. gmmproc předpokládá, že je tato technika použita, takže pokud tomu tak není, uvidíte chybové hlášení kompilátoru.

This compiler error might look like this:

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
or this:
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'

Takovéto věci se v knihovně v jazyce C opravují snadno, tak neváhejte poslat příslušnému správci záplatu.

G.6.2. Chybějící vlastnosti

By convention, glib/GTK-style objects have *_new() functions, such as example_widget_new() that do nothing more than call g_object_new() and return the result. The input parameters are supplied to g_object_new() along with the names of the properties for which they are values. For instance,

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

To umožňuje vazbám mezi různými programovacími jazyky implementovat jejich vlastní ekvivalenty (jako jsou konstruktory v C++), bez použití funkce *_new(). Často je to nutné, protože mohou ve skutečnosti vytvářet instanci odvozenin GType, do kterých přidají vlastní háčky pro obsluhu signálů a virtuálních funkcí.

Minimálně by funkce _new() neměla používat žádné privátní API (funkce, které jsou jen v souboru .c). Dokonce i v případě, že neexistují žádné funkce, můžeme napsat dva až tři řádky kódu s implementací funkce _new(), pokud tyto řádky kódu používají API, které je pro nás dostupné.

Another workaround is to add a *_construct() function that the C++ constructor can call after instantiating its own type. For instance,

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);
}

Provést opravu přidání vlastností a zajištěním, že budou spolu navzájem správně komunikovat, je v knihovně v jazyce C relativně obtížné, ale není to nemožné. Takže vyplňte chybové hlášení a zkuste příslušnému správci poslat záplatu.