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
- G.6.2. Chybějící vlastnosti
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
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.