i came from a java background and i'm trying to work with the c language. Now, java being object oriented and all, i tried to work with the GObject lib from the GTK+ project, i read some source code app (Anjuta mainly), and here is my sample code :
product.h
#pragma once
/*
class produit : id, name, price, description
*/
#include <gtk/gtk.h>
#include <glib-object.h>
/*
* Type macros.
*/
#define TYPE_PRODUCT (product_get_type())
#define PRODUCT(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), TYPE_PRODUCT, Product))
#define IS_PRODUCT(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), TYPE_PRODUCT))
#define PRODUCT_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), TYPE_PRODUCT, ProductClass))
#define IS_PRODUCT_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), TYPE_PRODUCT))
#define PRODUCT_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), TYPE_PRODUCT, ProductClass))
typedef struct _Product Product;
typedef struct _ProductClass ProductClass;
struct _Product
{
GObject parent_instance;
gint id;
gchar* name;
gdouble price;
gchar* description;
};
/* class */
struct _ProductClass
{
GObjectClass parent_class;
};
gint product_get_id(Product* self);
void product_set_id(Product* self, gint _id);
gchar product_get_name(Product* self);
void product_set_name(Product* self, gchar* _name);
gdouble product_get_price(Product* self);
void product_set_price(Product* self, gdouble _price);
gchar product_get_description(Product* self);
void product_set_description(Product* self, gchar* _description);
void product_print(Product* self);
GType product_get_type(void);
procuct.c
#include "product.h"
G_DEFINE_TYPE(Product, product, G_TYPE_OBJECT);
static void product_finalize(GObject* obj)
{
Product* self;
self = PRODUCT(obj);
g_free(self->name);
g_free(self->description);
G_OBJECT_CLASS(product_parent_class)->finalize(obj);
}
static void product_class_init(ProductClass* klass)
{
G_OBJECT_CLASS(klass)->finalize = product_finalize;
}
static void product_init(Product* self)
{
product_set_id(PRODUCT(self), 0);
product_set_name(PRODUCT(self), "_name");
product_set_price(PRODUCT(self), 0.0);
product_set_description(PRODUCT(self), "_description");
}
Product* product_new(gint _id, gchar* _name, gdouble _price, gchar* _description)
{
Product* self = NULL;
self = (Product*)g_object_new(TYPE_PRODUCT, NULL);
product_set_id(PRODUCT(self), _id);
product_set_name(PRODUCT(self), _name);
product_set_price(PRODUCT(self), _price);
product_set_description(PRODUCT(self), _description);
return self;
}
gint product_get_id(Product* self)
{
g_return_if_fail(IS_PRODUCT(self));
return self->id;
}
void product_set_id(Product* self, gint _id)
{
g_return_if_fail(IS_PRODUCT(self));
self->id = _id;
}
gchar product_get_name(Product* self)
{
g_return_if_fail(IS_PRODUCT(self));
return self->name;
}
void product_set_name(Product* self, gchar* _name)
{
g_return_if_fail(IS_PRODUCT(self));
self->name = _name;
}
gdouble product_get_price(Product* self)
{
g_return_if_fail(IS_PRODUCT(self));
return self->price;
}
void product_set_price(Product* self, gdouble _price)
{
g_return_if_fail(IS_PRODUCT(self));
self->price = _price;
}
gchar product_get_description(Product* self)
{
g_return_if_fail(IS_PRODUCT(self));
return self->description;
}
void product_set_description(Product* self, gchar* _description)
{
g_return_if_fail(IS_PRODUCT(self));
self->description = _description;
}
/* Object non-virtual method */
void product_print(Product* self)
{
g_return_if_fail(IS_PRODUCT(self));
g_print("Id - %i\n", self->id);
g_print("nom - %s\n", self->name);
g_print("prix - %f\n", self->price);
g_print("description - %s\n", self->description);
}
main.c
#include <gtk/gtk.h>
#include "product.h"
int main(int argc, char* argv[])
{
g_type_init();
Product* bar = g_object_new(TYPE_PRODUCT, NULL);
bar = product_new(15, "test p", 235.00,"juste");
product_print(bar);
product_set_price(bar, 20);
product_set_description(bar, "c'est un succés");
product_print(bar);
product_finalize(bar);
return 0;
}
nothing fancy, but i get the bunch of errors:
/bin/sh -c '/usr/bin/make -j4 -e -f Makefile'
----------Building project:[ GTK_object_test - Debug ]----------
make[1]: Entering directory '/home/abdelghani/workspace/codelite/GTK_object_test'
cc1: warning: command line option '-std=c++11' is valid for C++/ObjC++ but not for C
/usr/bin/gcc -c "/home/abdelghani/workspace/codelite/GTK_object_test/main.c" -g -O0 -std=c++11 -Wall -pthread -I/usr/include/gtk-3.0 -I/usr/include/at-spi2-atk/2.0 -I/usr/include/at-spi-2.0 -I/usr/include/dbus-1.0 -I/usr/lib/x86_64-linux-gnu/dbus-1.0/include -I/usr/include/gtk-3.0 -I/usr/include/gio-unix-2.0/ -I/usr/include/cairo -I/usr/include/pango-1.0 -I/usr/include/harfbuzz -I/usr/include/pango-1.0 -I/usr/include/atk-1.0 -I/usr/include/cairo -I/usr/include/pixman-1 -I/usr/include/freetype2 -I/usr/include/libpng12 -I/usr/include/gdk-pixbuf-2.0 -I/usr/include/libpng12 -I/usr/include/glib-2.0 -I/usr/lib/x86_64-linux-gnu/glib-2.0/include -o ./Debug/main.c.o -I. -I.
/usr/bin/gcc -c "/home/abdelghani/workspace/codelite/GTK_object_test/product.c" -g -O0 -std=c++11 -Wall -pthread -I/usr/include/gtk-3.0 -I/usr/include/at-spi2-atk/2.0 -I/usr/include/at-spi-2.0 -I/usr/include/dbus-1.0 -I/usr/lib/x86_64-linux-gnu/dbus-1.0/include -I/usr/include/gtk-3.0 -I/usr/include/gio-unix-2.0/ -I/usr/include/cairo -I/usr/include/pango-1.0 -I/usr/include/harfbuzz -I/usr/include/pango-1.0 -I/usr/include/atk-1.0 -I/usr/include/cairo -I/usr/include/pixman-1 -I/usr/include/freetype2 -I/usr/include/libpng12 -I/usr/include/gdk-pixbuf-2.0 -I/usr/include/libpng12 -I/usr/include/glib-2.0 -I/usr/lib/x86_64-linux-gnu/glib-2.0/include -o ./Debug/product.c.o -I. -I.
cc1: warning: command line option '-std=c++11' is valid for C++/ObjC++ but not for C
cc1: warning: command line option '-std=c++11' is valid for C++/ObjC++ but not for C
/home/abdelghani/workspace/codelite/GTK_object_test/main.c: In function 'main':
/home/abdelghani/workspace/codelite/GTK_object_test/main.c:6:5: warning: 'g_type_init' is deprecated (declared at /usr/include/glib-2.0/gobject/gtype.h:679) [-Wdeprecated-declarations]
g_type_init();
^
/home/abdelghani/workspace/codelite/GTK_object_test/main.c:9:5: warning: implicit declaration of function 'product_new' [-Wimplicit-function-declaration]
bar = product_new(15, "test p", 235.00,"juste");
^
/home/abdelghani/workspace/codelite/GTK_object_test/main.c:9:9: warning: assignment makes pointer from integer without a cast
bar = product_new(15, "test p", 235.00,"juste");
^
/home/abdelghani/workspace/codelite/GTK_object_test/main.c:15:5: warning: implicit declaration of function 'product_finalize' [-Wimplicit-function-declaration]
product_finalize(bar);
^
/home/abdelghani/workspace/codelite/GTK_object_test/product.c: In function 'product_get_name':
/home/abdelghani/workspace/codelite/GTK_object_test/product.c:65:5: warning: return makes integer from pointer without a cast
return self->name;
^
/home/abdelghani/workspace/codelite/GTK_object_test/product.c: In function 'product_get_description':
/home/abdelghani/workspace/codelite/GTK_object_test/product.c:89:5: warning: return makes integer from pointer without a cast
return self->description;
^
/usr/bin/g++ -o ./Debug/GTK_object_test @"GTK_object_test.txt" -L. -lgtk-3 -lgdk-3 -lpangocairo-1.0 -lpango-1.0 -latk-1.0 -lcairo-gobject -lcairo -lgdk_pixbuf-2.0 -lgio-2.0 -lgobject-2.0 -lglib-2.0
./Debug/main.c.o: In function `main':
/home/abdelghani/workspace/codelite/GTK_object_test/main.c:15: undefined reference to `product_finalize'
collect2: error: ld returned 1 exit status
GTK_object_test.mk:76: recipe for target 'Debug/GTK_object_test' failed
make[1]: *** [Debug/GTK_object_test] Error 1
make[1]: Leaving directory '/home/abdelghani/workspace/codelite/GTK_object_test'
Makefile:4: recipe for target 'All' failed
make: *** [All] Error 2
====2 errors, 6 warnings====
can anyone teach me whats the deal with cast warnings and the unreferenced issue?? Thx
There are various issues with your code example.
You seem to be compiling this C code with a C++ compiler; don't, use a C compiler.
You're calling:
bar = g_object_new (...);
right before:
bar = product_new (...);
which will leak the first instance.
You're also calling product_finalize()
, which is a static function — hence why you're getting a compiler error.
The finalize()
implementation will be called when the last reference on a GObject
instance is dropped; you're not supposed to be calling it yourself. Use g_object_unref()
, instead, to drop the reference on your object instances.