Ich wollte die GObject API versuchen. Die Idee ist, eine Vehicule-Klasse zu erstellen, die eine DERIVABLE
Art ist und eine Unterklasse von Vehicule namens Car zu erstellen, die ein FINAL
Typ ist. Mein Problem ist, dass, wenn ich in einem kleinen Programm versuche, eine Klasse Car zu erstellen, mein Programm blockiert und nicht bei der Erstellung der Instanz zurückkehrt.GObject Unterklasse in C kann keine Unterklasseninstanz erstellen
Hier ist der Mindestcode, um mein Problem zu reproduzieren. Ich benutze das Konventionstuto-Vehicule/Tuto-Auto.
tuto-vehicule.h
#ifndef __TUTO_VEHICULE_H__
#define __TUTO_VEHICULE_H__
#include <glib-object.h>
G_BEGIN_DECLS
typedef struct _TutoVehiculePrivate {
GObject parent_instance;
GString *name;
guint nb_wheels;
} TutoVehiculePrivate;
typedef struct _TutoVehiculeClass {
GObjectClass parent_class;
} TutoVehiculeClass;
#define TUTO_TYPE_VEHICULE tuto_vehicule_get_type()
G_DECLARE_DERIVABLE_TYPE(TutoVehicule, tuto_vehicule, TUTO, VEHICULE, GObject);
TutoVehicule *tuto_vehicule_new (void);
void tuto_vehicule_set_name(TutoVehicule *self, gchar *name);
void tuto_vehicule_set_nb_wheels(TutoVehicule *self, gint nb_wheels);
void tuto_vehicule_print_name(TutoVehicule *self);
void tuto_vehicule_print_nb_wheels(TutoVehicule *self);
G_END_DECLS
#endif
tuto-vehicule.c
#include "tuto-vehicule.h"
#include <stdio.h>
G_DEFINE_TYPE_WITH_PRIVATE(TutoVehicule, tuto_vehicule, G_TYPE_OBJECT);
static void
tuto_vehicule_dispose(GObject *object)
{
TutoVehiculePrivate *priv = tuto_vehicule_get_instance_private(TUTO_VEHICULE(object));
printf("tuto_vehicule_dispose\n");
g_string_free(priv->name, TRUE);
G_OBJECT_CLASS(tuto_vehicule_parent_class)->dispose(object);
}
static void
tuto_vehicule_class_init(TutoVehiculeClass *klass)
{
GObjectClass *g_object_class = G_OBJECT_CLASS(klass);
/* instance destructor*/
g_object_class->dispose = tuto_vehicule_dispose;
printf("tuto_vehicule_class_init for TutoVehiculeClass created by G_DECLARE_DERIVABLE_TYPE\n");
}
static void
tuto_vehicule_init(TutoVehicule *self)
{
TutoVehiculePrivate *priv = tuto_vehicule_get_instance_private(self);
priv->name = g_string_new(NULL);
priv->nb_wheels = 0;
printf("tuto_vehicule_init\n");
}
TutoVehicule *
tuto_vehicule_new(void)
{
TutoVehicule *vehicule_instance = g_object_new(TUTO_TYPE_VEHICULE, NULL);
return vehicule_instance;
}
void tuto_vehicule_set_name(TutoVehicule *self, gchar *name)
{
TutoVehiculePrivate *priv = tuto_vehicule_get_instance_private(self);
g_string_assign(priv->name, name);
}
void tuto_vehicule_set_nb_wheels(TutoVehicule *self, gint nb_wheels)
{
TutoVehiculePrivate *priv = tuto_vehicule_get_instance_private(self);
priv->nb_wheels = nb_wheels;
}
void tuto_vehicule_print_name(TutoVehicule *self)
{
TutoVehiculePrivate *priv = tuto_vehicule_get_instance_private(self);
printf("Vehicule name: %s\n", priv->name->str);
}
void tuto_vehicule_print_nb_wheels(TutoVehicule *self)
{
TutoVehiculePrivate *priv = tuto_vehicule_get_instance_private(self);
printf("Vehicule number of wheels: %d\n", priv->nb_wheels);
}
tuto-car.h
#ifndef __TUTO_CAR_H
#define __TUTO_CAR_H
#include "tuto-vehicule.h"
#include <glib-object.h>
G_BEGIN_DECLS
#define TUTO_TYPE_CAR tuto_car_get_type()
G_DECLARE_FINAL_TYPE(TutoCar, tuto_car, TUTO, CAR, TutoVehicule);
typedef struct _TutoCar {
TutoVehicule parent_instance;
} TutoCar;
TutoCar *tuto_car_new(void);
void tuto_car_print_name(TutoCar *self);
void tuto_car_print_nb_wheels(TutoCar *self);
G_END_DECLS
#endif
Tuto-car.c
#include "tuto-car.h"
#include <stdio.h>
G_DEFINE_TYPE(TutoCar, tuto_car, TUTO_TYPE_CAR);
static void
tuto_car_class_init(TutoCarClass *klass)
{
printf("tuto_car_class_init\n");
}
static void
tuto_car_init(TutoCar *self)
{
printf("tuto_car_init\n");
}
TutoCar *
tuto_car_new(void)
{
TutoCar *car = g_object_new(TUTO_TYPE_CAR, NULL);
tuto_vehicule_set_name(TUTO_VEHICULE(car), "car");
tuto_vehicule_set_nb_wheels(TUTO_VEHICULE(car), 4);
return car;
}
void
tuto_car_print_name(TutoCar *self)
{
tuto_vehicule_print_name(TUTO_VEHICULE(self));
}
void
tuto_car_print_nb_wheels(TutoCar *self)
{
tuto_vehicule_print_nb_wheels(TUTO_VEHICULE(self));
}
ich diese zwei Klassen in einer einfachen Haupt Datei:
#include <stdio.h>
#include "tuto-vehicule.h"
#include "tuto-car.h"
int main(int argc, char **argv)
{
printf("Create a TutoVehicule instance\n");
TutoVehicule *moto = tuto_vehicule_new();
printf("Puts its name to moto\n");
tuto_vehicule_set_name(moto, "moto");
printf("Puts its number of wheels to 2\n");
tuto_vehicule_set_nb_wheels(moto, 2);
printf("Create a TutoCar instance\n");
TutoCar *car = tuto_car_new();
printf("Use methods instance\n");
tuto_vehicule_print_name(moto);
tuto_vehicule_print_nb_wheels(moto);
tuto_vehicule_print_name(TUTO_VEHICULE(car));
tuto_vehicule_print_nb_wheels(TUTO_VEHICULE(car));
tuto_car_print_name(car);
tuto_car_print_nb_wheels(car);
printf("Destroy the instances created previously\n");
g_object_unref(car);
g_object_unref(moto);
return 0;
}
Die Zusammenstellung arbeitet mit:
gcc -Wall -o main_vehicule `pkg-config --libs --cflags gobject-2.0` main_vehicule.c tuto-car.c tuto-vehicule.c
Aber wenn ich das Programm ausführen Wie ich unten gesagt habe, habe ich diese Ausgabe und den Programmblock ohne zurückzusenden oder Fehlermeldungen auszugeben:
Create a TutoVehicule instance
tuto_vehicule_class_init for TutoVehiculeClass created by G_DECLARE_DERIVABLE_TYPE
tuto_vehicule_init
Puts its name to moto
Puts its number of wheels to 2
Create a TutoCar instance
Ich weiß, dass mein Programm Block an dieser Aussage:
TutoCar *car = g_object_new(TUTO_TYPE_CAR, NULL);
Was habe ich verpasst? Die offiziellen Dokumente sind nicht wirklich klar.
bearbeiten
Hier ist eine GDB-Sitzung:
(gdb) break tuto-car.c:tuto_car_new
Breakpoint 1 at 0x400dcb: file tuto-car.c, line 21.
(gdb) run
Starting program: /home/cedlemo/Projets/C/GObject/derivable_type/main_vehicule
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/usr/lib/libthread_db.so.1".
Create a TutoVehicule instance
tuto_vehicule_class_init for TutoVehiculeClass created by G_DECLARE_DERIVABLE_TYPE
tuto_vehicule_init
Puts its name to moto
Puts its number of wheels to 2
Create a TutoCar instance
Breakpoint 1, tuto_car_new() at tuto-car.c:21
21 TutoCar *car = g_object_new(TUTO_TYPE_CAR, NULL);
(gdb) backtrace
#0 tuto_car_new() at tuto-car.c:21
#1 0x0000000000400c02 in main (argc=1, argv=0x7fffffffded8) at main_vehicule.c:16
(gdb) next
Der Programmblock in gdb auch so hatte ich ctrl + c und prüfen Sie den Stapel schlagen:
(gdb) backtrace
#0 0x00007ffff75ba269 in syscall() from /usr/lib/libc.so.6
#1 0x00007ffff790618f in g_cond_wait() from /usr/lib/libglib-2.0.so.0
#2 0x00007ffff78e8437 in g_once_init_enter() from /usr/lib/libglib-2.0.so.0
#3 0x0000000000400d1e in tuto_car_get_type() at tuto-car.c:4
#4 0x0000000000400d44 in tuto_car_get_type() at tuto-car.c:4
#5 0x0000000000400dd0 in tuto_car_new() at tuto-car.c:21
#6 0x0000000000400c02 in main (argc=1, argv=0x7fffffffded8) at main_vehicule.c:16
beachten Sie bitte Folgendes: "Beachten Sie, dass Symbole, die mit doppeltem Unterstrich oder Unterstrich und einem Großbuchstaben beginnen, unbedingt für die Implementierung reserviert sind. Systemköpfe verwenden Namen mit doppelten Unterstrichen - sie sind Teil der Implementierung Es ist nicht erlaubt, Ihren Namensraum zu verschmutzen. Sie sollten ihren Namensraum nicht verschmutzen. Behandeln Sie Namen, die mit Unterstrich beginnen, für alle Compiler, auch wenn sie für den Compiler reserviert sind. " – user3629249
@ user3629249, wenn Sie einen Verweis haben Zum Beispiel zu "TutoCar" oder "TutoVehiculePrivate" folge ich zum Beispiel der GObject-Konvention: https://developer.gnome.org/gobject/2.48/howto-gobject.html oder https://developer.gnome.org/gobject/2.48/ howto-gobject-code.html – cedlemo
Ich realisiere, dass dies wirklich ein sehr kleines Beispiel ist, da GObject Code leider sehr ausführlich ist; Sie können es minimaler machen, indem Sie den Namen und die Anzahl der Radeigenschaften ausschneiden und sehen, ob das irgendwas beeinflusst. In jedem Fall würde ich einen Debugger verwenden, um zu sehen, wo das Programm _really_ friert, anstatt sich auf Druckanweisungen zu verlassen. Für jetzt werde ich wählen, um wieder zu öffnen, wie ich denke, dass die Problemaussage klar ist. – ptomato