Los archivos .hg y .ccg
Los archivos de fuentes .hg y .ccg se parecen mucho a los archivos de fuentes .h y .cc de C++, pero contienen macros adicionales, como _CLASS_GOBJECT() y _WRAP_METHOD(), desde las que gmmproc genera código fuente de C++ apropiado, generalmente en la misma posición en la cabecera. Cualquier código fuente adicional de C++ se copiará tal cual en el archivo .h o .cc correspondiente.
Un archivo .hg típicamente incluirá algunas cabeceras y luego declarará una clase, usando algunas macros para añadir una API o comportamiento a esta clase. Por ejemplo, el button.hg de gtkmm se ve más o menos así:
#include <gtkmm/bin.h> #include <gtkmm/activatable.h> #include <gtkmm/stockid.h> _DEFS(gtkmm,gtk) _PINCLUDE(gtkmm/private/bin_p.h) namespace Gtk { class Button : public Bin, public Activatable { _CLASS_GTKOBJECT(Button,GtkButton,GTK_BUTTON,Gtk::Bin,GtkBin) _IMPLEMENTS_INTERFACE(Activatable) public: _CTOR_DEFAULT explicit Button(const Glib::ustring& label, bool mnemonic = false); explicit Button(const StockID& stock_id); _WRAP_METHOD(void set_label(const Glib::ustring& label), gtk_button_set_label) ... _WRAP_SIGNAL(void clicked(), "clicked") ... _WRAP_PROPERTY("label", Glib::ustring) }; } // namespace Gtk
Las macros en este ejemplo hacen lo siguiente:
- _DEFS()
Especifica la carpeta de destino para las fuentes generadas, y el nombre del archivo .defs principal que gmmproc debe procesar.
- _PINCLUDE()
Le dice a gmmproc que incluya una cabecera desde el archivo private/button_p.h generado.
- _CLASS_GTKOBJECT()
Le dice a gmmproc que añada algunos «typedefs», constructores, y métodos estándar a esta clase, como es apropiado cuando se envuelve un widget.
- _IMPLEMENTS_INTERFACE()
Le dice a gmmproc que añada código de inicialización para la interfaz.
- _CTOR_DEFAULT
Añadir un constructor predeterminado.
- _WRAP_METHOD(), _WRAP_SIGNAL(), y _WRAP_PROPERTY()
Añadir métodos para envolver las partes de la API de C.
Los archivos .h y .cc se generarán desde los archivos .hg y .ccg procesándolos con gmmproc así, aunque esto sucede automáticamente cuando usa la estructura de construcción anteriormente mencionada:
$ cd gtk/src $ /usr/lib/glibmm-2.4/proc/gmmproc -I ../../tools/m4 --defs . button . ./../gtkmm
Tenga en cuenta que se le proporcionó a gmmproc la ruta de los archivos de conversión .m4, la ruta del archivo .defs, el nombre de un archivo .hg, la carpeta de las fuentes, y la carpeta de destino.
Debe evitar incluir la cabecera de C desde su cabecera de C++, para evitar contaminar el espacio de nombres global, y para evitar exportar API pública innecesaria. Pero necesitará incluir las cabeceras de C desde su archivo .ccg.
Las macros se explican en mayor detalle en las secciones siguientes.
- G.3.1. Conversiones m4
- G.3.2. Inicializaciones de m4
- G.3.3. Macros de clases
- G.3.4. Macros de constructores
- G.3.5. Macros de métodos
- G.3.6. Otras macros
- G.3.7. Tipos básicos
G.3.1. Conversiones m4
Las macros que usa en los archivos .hg y .ccg a menudo necesitan saber cómo convertir un tipo de C++ a un tipo de C, o viceversa. gmmproc toma esta información desde un archivo .m4 en su carpeta tools/m4/. Esto le permite llamar a una función de C en la implementación de su método de C++, pasándole los parámetros apropiados a esa función de C. Por ejemplo, esto le dice a gmmproc cómo convertir un puntero de GtkTreeView a un puntero de Gtk::TreView:
_CONVERSION(`GtkTreeView*',`TreeView*',`Glib::wrap($3)')
$3 se reemplazará por el nombre del parámetro cuando gmmproc use esta conversión.
Algunas macros adicionales hacen esto más fácil y consistente. Consulte los archivos .m4 de gtkmm como ejemplos. Por ejemplo:
_CONVERSION(`PrintSettings&',`GtkPrintSettings*',__FR2P) _CONVERSION(`const PrintSettings&',`GtkPrintSettings*',__FCR2P) _CONVERSION(`const Glib::RefPtr<Printer>&',`GtkPrinter*',__CONVERT_REFPTR_TO_P($3))
G.3.2. Inicializaciones de m4
Cuando se envuelven métodos, a menudo es deseable almacenar el valor que devuelve una función de C en lo que se conoce como parámetro de salida. En este caso, el método de C++ devuelve void pero se incluye en su lista de argumentos un parámetro de salida en el que se almacena el valor de la función de C. gmmproc permite esta funcionalidad, pero deben incluirse macros de inicialización apropiadas para decirle a gmmproc cómo inicializar el parámetro de C++ desde el valor de devolución de la función de C.
Por ejemplo, si hubiera una función de C que devolviera un GtkWidget* y por alguna razón, en lugar de hacer que el método de C++ también devuelva el widget, se quisiera hacer que el método de C++ ponga al widget en un parámetro de salida especificado, sería necesaria una macro de inicialización como la siguiente:
_INITIALIZATION(`Gtk::Widget&',`GtkWidget*',`$3 = Glib::wrap($4)')
$3 se reemplazará por el nombre del parámetro de salida del método de C++ y $4 se reemplazará por el valor de retorno de la función de C cuando gmmproc use esta inicialización. Por conveniencia, $1 también se reemplazará por el tipo de C++ sin el «et» (&) y $2 se reemplazará por el tipo de C.
G.3.3. Macros de clases
Las macros de clases declaran la clase en sí y su relación con el tipo de C subyacente. Generan algunos constructores internos, el miembro gobject_, «typedefs», los gobj() de acceso, registro de tipos, y el método Glib::wrap(), entre otras cosas.
Otras macros, como _WRAP_METHOD() y _WRAP_SIGNAL() sólo pueden usarse después de una llamada a una macro _CLASS_*.
- G.3.3.1. _CLASS_GOBJECT
- G.3.3.2. _CLASS_GTKOBJECT
- G.3.3.3. _CLASS_BOXEDTYPE
- G.3.3.4. _CLASS_BOXEDTYPE_STATIC
- G.3.3.5. _CLASS_OPAQUE_COPYABLE
- G.3.3.6. _CLASS_OPAQUE_REFCOUNTED
- G.3.3.7. _CLASS_GENERIC
- G.3.3.8. _CLASS_INTERFACE
G.3.3.1. _CLASS_GOBJECT
Esta macro declara un envoltorio de un tipo que deriva de GObject, pero cuyo envoltorio no deriva de Gtk::Object.
_CLASS_GOBJECT( C++ class, C class, C casting macro, C++ base class, C base class )
Por ejemplo, de accelgroup.hg:
_CLASS_GOBJECT(AccelGroup, GtkAccelGroup, GTK_ACCEL_GROUP, Glib::Object, GObject)
G.3.3.2. _CLASS_GTKOBJECT
Esta macro declara un envoltorio para un tipo cuyo envoltorio deriva de Gtk::Object, como un widget o un diálogo.
_CLASS_GTKOBJECT( C++ class, C class, C casting macro, C++ base class, C base class )
Por ejemplo, de button.hg:
_CLASS_GTKOBJECT(Button, GtkButton, GTK_BUTTON, Gtk::Bin, GtkBin)
Típicamente usará esta macro cuando la clase ya derive de Gtk::Object. Por ejemplo, la usará cuando envuelva un widget de GTK+, porque Gtk::Widget deriva de Gtk::Object.
También podrá derivar clases que no sean widgets de Gtk::Object para que puedan usarse sin Glib::RefPtr. Por ejemplo, podrían instanciarse con Gtk::manage() o en la pila como una variable miembro. Esto es cómodo, pero sólo debe usarlo cuando esté seguro de que no se necesita conteo de referencias real. Se considera de utilidad para los widgets.
G.3.3.3. _CLASS_BOXEDTYPE
Esta macro declara un envoltorio para una estructura que no es GObject, registrada con g_boxed_type_register_static().
_CLASS_BOXEDTYPE( C++ class, C class, new function, copy function, free function )
Por ejemplo, para Gdk::Color:
_CLASS_BOXEDTYPE(Color, GdkColor, NONE, gdk_color_copy, gdk_color_free)
G.3.3.4. _CLASS_BOXEDTYPE_STATIC
Esta macro declara un envoltorio para una estructura asignable simple como GdkRectangle. Es similar a _CLASS_BOXEDTYPE, pero la estructura de C no se asigna dinámicamente.
_CLASS_BOXEDTYPE_STATIC( C++ class, C class )
Por ejemplo, para Gdk::Rectangle:
_CLASS_BOXEDTYPE_STATIC(Rectangle, GdkRectangle)
G.3.3.5. _CLASS_OPAQUE_COPYABLE
Esta macro declara un envoltorio para una estructura opaca que tiene funciones «copy» y «free». Las funciones «new», «copy» y «free» se usarán para instanciar el constructor predeterminado, copiar el constructor y el destructor.
_CLASS_OPAQUE_COPYABLE( C++ class, C class, new function, copy function, free function )
Por ejemplo, de stockitem.hg:
_CLASS_OPAQUE_COPYABLE(StockItem, GtkStockItem, NONE, gtk_stock_item_copy, gtk_stock_item_free)
G.3.3.6. _CLASS_OPAQUE_REFCOUNTED
Esta macro declara un envoltorio para una estructura opaca con conteo de referencias. El envoltorio de C++ no puede instanciarse directamente y sólo lo puede usar Glib::RefPtr.
_CLASS_OPAQUE_REFCOUNTED( C++ class, C class, new function, ref function, unref function )
Por ejemplo, para Pango::Coverage:
_CLASS_OPAQUE_REFCOUNTED(Coverage, PangoCoverage, pango_coverage_new, pango_coverage_ref, pango_coverage_unref)
G.3.3.7. _CLASS_GENERIC
Esta macro puede usarse para envolver estructuras que no se ajustan a ninguna categoría especializada.
_CLASS_GENERIC( C++ class, C class )
Por ejemplo, para Pango::AttrIter:
_CLASS_GENERIC(AttrIter, PangoAttrIterator)
G.3.3.8. _CLASS_INTERFACE
Esta macro declara un envoltorio para un tipo que deriva de GTypeInterface.
_CLASS_INTERFACE( C++ class, C class, C casting macro, C interface struct, Base C++ class (optional), Base C class (optional) )
Por ejemplo, de celleditable.hg:
_CLASS_INTERFACE(CellEditable, GtkCellEditable, GTK_CELL_EDITABLE, GtkCellEditableIface)
Hay dos parámetros adicionales opcionales, para el caso de que la interfaz derive de otra interfaz, que debe ser cuando la «GInterface» tenga otra «GInterface» como requisito previo. Por ejemplo, de loadableicon.hg:
_CLASS_INTERFACE(LoadableIcon, GLoadableIcon, G_LOADABLE_ICON, GLoadableIconIface, Icon, GIcon)
G.3.4. Macros de constructores
Las macros _CTOR_DEFAULT() y _WRAP_CTOR() añaden constructores, envolviendo las funciones de C *_new() especificadas. Estas macros asumen que el objeto de C tiene propiedades con los mismos nombres que los parámetros de función, como es usual, para que pueda proporcionar los parámetros directamente a una llamada de g_object_new(). Estos constructores nunca llaman realmente a funciones de C *_new(), porque gtkmm debe en realidad instanciar «GTypes» derivados, y las funciones *_new() de C sólo están pensadas como funciones cómodas para programadores de C.
Cuando use _CLASS_GOBJECT(), los constructores deben declararse protegidos (en lugar de públicos) y cada constructor debe tener un _WRAP_CREATE() correspondiente en la sección pública. Esto evita que la clase se instancie sin usar un RefPtr. Por ejemplo:
class ActionGroup : public Glib::Object { _CLASS_GOBJECT(ActionGroup, GtkActionGroup, GTK_ACTION_GROUP, Glib::Object, GObject) protected: _WRAP_CTOR(ActionGroup(const Glib::ustring& name = Glib::ustring()), gtk_action_group_new) public: _WRAP_CREATE(const Glib::ustring& name = Glib::ustring())
- G.3.4.1. _CTOR_DEFAULT
- G.3.4.2. _WRAP_CTOR
- G.3.4.3. Escribir constructores a mano
G.3.4.2. _WRAP_CTOR
Esta macro crea un constructor con argumentos, equivalente a una función de C *_new(). En realidad no llamará a la función *_new(), sino que simplemente creará un constructor equivalente con los mismos tipos de argumentos. Toma una firma de constructor de C++ y un nombre de función de C.
También toma un argumento opcional adicional:
- errthrow
-
Esto le dice a gmmproc que el *_new() de C tiene un parámetro GError** final que debe ignorarse.
Cuando envuelve constructores, es posible que gmmproc genere sobrecargas cómodas de los constructores envueltos si la función de C tiene parámetros que son opcionales (esto significa que la API de C permite asignar «null» a esos parámetros). Por ejemplo, para especificar si un parámetro es opcional, la macro _WRAP_CTOR() sería similar a la que se muestra a continuación:
_WRAP_CTOR(ToolButton(Widget& icon_widget, const Glib::ustring& label{?}), gtk_tool_button_new)
También es posible tener un orden de los parámetros del constructor distinto a los de la función de C usando la función de mapeo de parámetros de C++ a C de gmmproc. El uso de esta función hace posible mapear un parámetro de C++ a uno de C mediante la especificación del nombre del parámetro de C. Por ejemplo, si se asume que la declaración de la función gtk_tool_button_new() es la siguiente:
GtkToolItem* gtk_tool_button_new(GtkWidget* icon_widget, const gchar* label);
_WRAP_CTOR(ToolButton(const Glib::ustring& label{label}, Widget& icon_widget{icon_widget}), gtk_tool_button_new)
_WRAP_CTOR(ToolButton(const Glib::ustring& label{.}, Widget& icon_widget{.}), gtk_tool_button_new)
Esta misma sintaxis de parámetro opcional y reordenamiento de parámetros están disponibles para _WRAP_CREATE(). gmmproc generaría sobrecargas de create() adicionales sin los parámetros opcionales especificados.
G.3.4.3. Escribir constructores a mano
Cuando un constructor debe escribirse a mano parcialmente porque, por ejemplo, los parámetros de la función de C *_new() no corresponden directamente a las propiedades del objeto, o porque la función de C *_new() hace más que llamar a g_object_new(), la macro _CONSTRUCT() se puede usar en el archivo .ccg para ahorrar trabajo. La macro _CONSTRUCT() toma una serie de nombres y valores de propiedades. Por ejemplo, de button.ccg:
Button::Button(const Glib::ustring& label, bool mnemonic) : _CONSTRUCT("label", label.c_str(), "use_underline", gboolean(mnemonic)) {}
G.3.5. Macros de métodos
- G.3.5.1. _WRAP_METHOD
- G.3.5.2. _WRAP_METHOD_DOCS_ONLY
- G.3.5.3. _IGNORE / _IGNORE_SIGNAL
- G.3.5.4. _WRAP_SIGNAL
- G.3.5.5. _WRAP_PROPERTY
- G.3.5.6. _WRAP_VFUNC
G.3.5.1. _WRAP_METHOD
Esta macro genera el método de C++ para envolver una función de C.
_WRAP_METHOD( C++ method signature, C function name)
Por ejemplo, de entry.hg:
_WRAP_METHOD(void set_text(const Glib::ustring& text), gtk_entry_set_text)
La función de C (por ejemplo, gtk_entry_set_text) se describe en mayor detalle en el archivo .defs, y los archivos convert*.m4 contienen la conversión necesaria del tipo de parámetro de C++ al tipo de C. Esta macro también genera comentarios de documentación de Doxygen basados en los archivos *_docs.xml y *_docs_override.xml.
Hay algunos argumentos opcionales adicionales:
- refreturn
-
Hace una reference() adicional en el valor de retorno, en el caso de que la función de C no proporcione una referencia.
- errthrow
-
Usa el último parámetro GError* de la función de C para lanzar una excepción.
- deprecated
-
Pone el código generado en bloques #ifdef. El texto que explica por qué se marca como obsoleto puede especificarse como un parámetro opcional.
- constversion
-
Sólo llama a la versión no constante de la misma función, en lugar de generar código casi duplicado.
- ifdef
-
Pone el código generado en bloques #ifdef.
- slot_name
-
Le dice a _WRAP_METHOD() el nombre del parámetro «slot» del método, si tiene uno. Esto le permite a «gmmproc» generar código para copiar el «slot» y pasarle la copia a la función de C en su parámetro gpointer user_data final. La opción slot_callback también debe usarse para especificar el nombre de la función de devolución de llamada adhesiva que pasar a la función de C.
- slot_callback
-
Usado junto con la opción slot_name para decirle a _WRAP_METHOD() el nombre de la función de devolución de llamada adhesiva que maneja la extracción del «slot» y su llamada. La dirección de esta devolución de llamada también se pasa a la función de C que el método envuelve.
- no_slot_copy
-
Le dice a «gmmproc» que no le pase una copia del «slot» a la función de C, si el método tiene una. En su lugar, se pasa el «slot» en sí. El nombre del parámetro «slot» y la función de devolución de llamada adhesiva deben haberse especificado con las opciones slot_name y slot_callbback respectivamente.
Al igual que con _WRAP_CTOR() es posible especificar si hay parámetros opcionales. Si este es el caso, gmmproc generará métodos de sobrecarga cómodos sin esos parámetros. Por ejemplo:
_WRAP_METHOD(void get_preferred_size(Requisition& minimum_size, Requisition& natural_size{?}) const, gtk_widget_get_preferred_size)
Además, al igual que con _WRAP_CTOR(), es posible reordenar los parámetros del método de C++ usando la función de mapeo de C++ a C de gmmproc. El uso de esta función hace posible mapear un parámetro de C++ a uno de C mediante la especificación del nombre del parámetro de C. Por ejemplo, si la declaración de gtk_widget_set_device_events() es la siguiete:
void gtk_widget_set_device_events(GtkWidget* widget, GdkDevice* device, GdkEventMask events);
_WRAP_METHOD(void set_device_events(Gdk::EventMask events{events}, const Glib::RefPtr<const Gdk::Device>& device{device}), gtk_widget_set_device_events)
_WRAP_METHOD(void set_device_events(Gdk::EventMask events{.}, const Glib::RefPtr<const Gdk::Device>& device{.}), gtk_widget_set_device_events)
Con _WRAP_METHOD() también es posible incluir un parámetro de salida en la declaración del método de C++ en el que se pone el valor de retorno de la función de C, y que el método de C++ devuelva void. Para hacer esto, simplemente incluya la declaración del parámetro de salida en la declaración del método de C++ adjuntando {OUT} al nombre del parámetro de salida. Por ejemplo, si gtk_widget_get_request_mode() se declara como sigue:
GtkSizeRequestMode gtk_widget_get_request_mode(GtkWidget* widget);
_WRAP_METHOD(void get_request_mode(SizeRequestMode& mode{OUT}) const, gtk_widget_get_request_mode)
_INITIALIZATION(`SizeRequestMode&',`GtkSizeRequestMode',`$3 = (SizeRequestMode)($4)')
_INITIALIZATION(`SizeRequestMode&',`GtkSizeRequestMode',`$3 = ($1)($4)')
_WRAP_METHOD() también soporta establecer parámetros de salida de C++ desde parámetros de salida de C si la función de C que está envolviendo los tiene. Suponga, por ejemplo, que quiere envolver la siguiente función de C que devuelve un valor en su parámetro de salida de C rect:
gboolean gtk_icon_view_get_cell_rect(GtkIconView* icon_view, GtkTreePath* path, GtkCellRenderer* cell, GdkRectangle* rect);
_WRAP_METHOD(bool get_cell_rect(const TreeModel::Path& path, const CellRenderer& cell, Gdk::Rectangle& rect{>>}) const, gtk_icon_view_get_cell_rect)
_INITIALIZATION(`Gdk::Rectangle&',`GdkRectangle', `$3 = Glib::wrap(&($4))')
Seleccionar qué tipos de C++ deben usarse también es importante cuando se envuelve una API de C. A pesar de que generalmente es obvio qué tipos de C++ deben usarse en el método de C++, aquí hay algunos consejos:
- Objetos usados a través de RefPtr: pase el RefPtr como una referencia constante. Por ejemplo, const Glib::RefPtr<Gtk::Action>& action.
- Objetos constantes usados a través de RefPtr: si la función no debe cambiar el objeto, asegúrese de que el objeto es constante, incluso si el RefPtr ya lo es. Por ejemplo, const Glib::RefPtr<const Gtk::Action>& action.
- Envolver parámetros GList* y GSList*: primero, necesita descubrir qué objetos están contenidos en los campos de datos de la lista por cada elemento, generalmente mediante la lectura de la documentación de la función de C. Un tipo std::vector podrá entonces envolver la lista. Por ejemplo, std::vector< Glib::RefPtr<Action> >. Tal vez necesite definir un tipo «Traits» para especificar cómo deben convertirse los tipos de C y C++.
- Envolver los tipos de retorno de GList* y GSList*: debe descubrir si el llamador debe liberar la lista y si debe liberar sus elementos, también mediante la lectura de la documentación de la función de C. Con esta información puede elegir la posesión (ninguna, superficial o profunda) para la regla de conversión m4, la que probablemente deba poner directamente en el archivo .hg porque la posesión depende de la función en lugar del tipo. Por ejemplo:
#m4 _CONVERSION(`GSList*',`std::vector<Widget*>',`Glib::SListHandler<Widget*>::slist_to_vector($3, Glib::OWNERSHIP_SHALLOW)')
G.3.5.2. _WRAP_METHOD_DOCS_ONLY
Esta macro es similar a _WRAP_METHOD(), pero sólo genera la documentación de un método de C++ que envuelve una función de C. Úsela cuando debe escribir el método a mano, pero quiere usar la documentación que se crearía si el método se generara.
_WRAP_METHOD_DOCS_ONLY(C function name)
Por ejemplo, de container.hg:
_WRAP_METHOD_DOCS_ONLY(gtk_container_remove)
G.3.5.3. _IGNORE / _IGNORE_SIGNAL
gmmproc le advertirá en stdout de funciones y señales que haya olvidado envolver, ayudándole a asegurarse que está envolviendo la API completa. Pero si no quiere envolver algunas funciones o señales, o si elige escribir a mano algunos métodos entonces puede usar las macros _IGNORE() o _IGNORE_SIGNAL() para hacer que gmmproc deje de quejarse.
_IGNORE(C function name 1, C function name2, etc)
_IGNORE_SIGNAL(C signal name 1, C signal name2, etc)
Por ejemplo, de buttonbox.hg:
_IGNORE(gtk_button_box_set_spacing, gtk_button_box_get_spacing)
G.3.5.4. _WRAP_SIGNAL
Esta macro genera la señal de C++ con el estilo de libsigc++ para envolver una señal GObject de C. En realidad genera un método de acceso público, como signal_clicked(), que devuelve un objeto sustituto. gmmproc usa el archivo .defs para descubrir los tipos de parámetro de C y los archivos de conversión .m4 para descubrir conversiones de tipo adecuadas.
_WRAP_SIGNAL( C++ signal handler signature, C signal name)
Por ejemplo, de button.hg:
_WRAP_SIGNAL(void clicked(),"clicked")
Las señales generalmente tienen punteros de funciones en la estructura de GTK, con un valor de enum correspondiente y un g_signal_new() en el archivo .c.
Hay algunos argumentos opcionales adicionales:
- no_default_handler
-
No genera un método virtual on_something() para permitir reemplazar fácilmente el manejador de señales predeterminado. Use esto si añadir una señal con un manejador de señales predeterminado rompe la ABI incrementando el tamaño de la tabla de funciones virtuales de la clase.
- custom_default_handler
-
Genera una declaración del método virtual on_something en el archivo .h, pero no genera una definición en el archivo .cc. Use esto cuando deba generar la definición a mano.
- custom_c_callback
-
No genera una devolución de llamada de C para la señal. Use esto cuando debe generar la función de devolución de llamada a mano.
- refreturn
-
Hace una reference() adicional en el valor de retorno del método virtual on_something(), en caso de que la función de C no proporcione una referencia.
- ifdef
-
Pone el código generado en bloques #ifdef.
G.3.5.5. _WRAP_PROPERTY
Esta macro genera el método de C++ que envuelve una propiedad GObject de C. Debe especificar el nombre de la propiedad y el tipo de C++ que quiere para la propiedad. gmmproc usa el archivo .defs para descubrir el tipo de C y el archivo de conversión .m4 para descubrir conversiones de tipo apropiadas.
_WRAP_PROPERTY(C property name, C++ type)
Por ejemplo, de button.hg:
_WRAP_PROPERTY("label", Glib::ustring)
G.3.5.6. _WRAP_VFUNC
Esta macro genera el método de C++ que envuelve una función virtual de C.
_WRAP_VFUNC( C++ method signature, C function name)
Por ejemplo, de widget.hg:
_WRAP_VFUNC(SizeRequestMode get_request_mode() const, get_request_mode)
La función de C (por ejemplo, get_request_mode) se describe en mayor detalle en el archivo *_vfuncs.defs, y los archivos convert*.m4 contienen las conversiones necesarias del tipo de parámetro de C++ al tipo de parámetro de C.
Hay algunos argumentos opcionales adicionales:
- refreturn
-
Hace una reference() adicional en el valor de retorno de la función something_vfunc(), en caso de que la función virtual de C no proporcione una referencia.
- refreturn_ctype
-
Hace una reference() adicional en el valor de retorno de una función something_vfunc() reemplazada en la función de devolución de llamada de C, en caso de que la función de C que llama espere que proporcione una referencia.
- errthrow
-
Usa el último parámetro GError* de la función virtual de C (si existe) para lanzar una excepción.
- custom_vfunc
-
No genera una definición de la «vfunc» en el archivo .cc. Use esto cuando deba generar la «vfunc» a mano.
- custom_vfunc_callback
-
No genera una función de devolución de llamada de C para la «vfunc». Use esto cuando deba generar la función de devolución de llamada a mano.
- ifdef
-
Pone el código generado en bloques #ifdef.
Una regla para la cual puede haber excepciones: si la función virtual de C devuelve un puntero a un objeto derivado de GObject, es decir un objeto cuyas referencias se cuentan, entonces la función virtual de C++ deberá devolver un objeto Glib::RefPtr<>. Se requiere uno de los argumentos adicionales refreturn o refreturn_ctype.
G.3.6. Otras macros
- G.3.6.1. _IMPLEMENTS_INTERFACE
- G.3.6.2. _WRAP_ENUM
- G.3.6.3. _WRAP_GERROR
- G.3.6.4. _MEMBER_GET / _MEMBER_SET
- G.3.6.5. _MEMBER_GET_PTR / _MEMBER_SET_PTR
- G.3.6.6. _MEMBER_GET_GOBJECT / _MEMBER_SET_GOBJECT
G.3.6.1. _IMPLEMENTS_INTERFACE
Esta macro genera código de inicialización para la interfaz.
_IMPLEMENTS_INTERFACE(C++ interface name)
Por ejemplo, de button.hg:
_IMPLEMENTS_INTERFACE(Activatable)
Hay un argumento opcional adicional:
- ifdef
-
Pone el código generado en bloques #ifdef.
G.3.6.2. _WRAP_ENUM
Esta macro genera una enum de C++ para envolver una enum de C. Debe especificar el nombre de C++ que quiere y el nombre de la enum de C subyacente.
Por ejemplo, de widget.hg:
_WRAP_ENUM(WindowType, GdkWindowType)
Si la enum no es un GType, debe pasar un tercer parámetro «NO_GTYPE». Este es el caso cuando no hay una función *_get_type() para la enum de C, pero tenga cuidado: no sólo necesita incluir una cabecera adicional para esa función, también debe enviar un informe de error de la API de C porque todas las enums deben registrarse como GTypes.
Por ejemplo, de icontheme.hg:
_WRAP_ENUM(IconLookupFlags, GtkIconLookupFlags, NO_GTYPE)
G.3.6.3. _WRAP_GERROR
Esta macro genera una clase de excepción de C++, derivada de Glib::Error, con una enum Code y un método code(). Debe especificar el nombre de C++ que quiere, el nombre de la enum de C correspondiente, y el prefijo de los valores de la enum de C.
Los métodos generados desde _WRAP_METHOD() podrán entonces lanzar esta excepción con la opción «errthrow».
Por ejemplo, de pixbuf.hg:
_WRAP_GERROR(PixbufError, GdkPixbufError, GDK_PIXBUF_ERROR)
G.3.6.4. _MEMBER_GET / _MEMBER_SET
Use estas macros si está envolviendo una estructura simple o un tipo en caja que proporciona acceso directo a sus miembros de datos, para crear métodos de acceso y modificación para estos.
_MEMBER_GET(C++ name, C name, C++ type, C type)
_MEMBER_SET(C++ name, C name, C++ type, C type)
Por ejemplo, en rectangle.hg:
_MEMBER_GET(x, x, int, int)
G.3.6.5. _MEMBER_GET_PTR / _MEMBER_SET_PTR
Use estas macros para proporcionar métodos de acceso y modificación para un miembro de datos que es de tipo puntero automáticamente. Para la función de acceso, creará dos métodos, uno constante y otro no constante.
_MEMBER_GET_PTR(C++ name, C name, C++ type, C type)
_MEMBER_SET_PTR(C++ name, C name, C++ type, C type)
Por ejemplo, para Pango::Analysis en item.hg:
// _MEMBER_GET_PTR(engine_lang, lang_engine, EngineLang*, PangoEngineLang*) // It's just a comment. It's difficult to find a real-world example.
G.3.6.6. _MEMBER_GET_GOBJECT / _MEMBER_SET_GOBJECT
Use estas macros para proporcionar métodos de acceso y modificación para un miembro de datos que es de tipo GObject que debe referenciarse antes de devolverse.
_MEMBER_GET_GOBJECT(C++ name, C name, C++ type, C type)
_MEMBER_SET_GOBJECT(C++ name, C name, C++ type, C type)
Por ejemplo, en Pangomm, layoutline.hg:
_MEMBER_GET_GOBJECT(layout, layout, Pango::Layout, PangoLayout*)
G.3.7. Tipos básicos
Algunos de los tipos básicos que se usan en las API de C tienen alternativas mejores en C++. Por ejemplo, no hay necesidad de un tipo gboolean dado que C++ tiene el bool. La siguiente lista muestra algunos tipos comúnmente usados en API de C y en qué los puede convertir en una biblioteca envoltorio de C++
Tipo de C: gboolean
Tipo de C++: bool
Tipo de C: gint
Tipo de C++: int
Tipo de C: guint
Tipo de C++: guint
Tipo de C: gdouble
Tipo de C++: doble
Tipo de C: gunichar
Tipo de C++: gunichar
Tipo de C: gchar*
Tipo de C++: Glib::ustring (o std::string para nombres de archivos)