GObject示例:未定义对`product_finalize'的引用?

时间:2016-03-10 08:57:00

标签: c gtk gobject

我来自java背景,我正在尝试使用c语言。现在,java是面向对象的,所有,我尝试使用GTK +项目中的GObject lib,我读了一些源代码应用程序(主要是Anjuta),这是我的示例代码:

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;
}
没有什么花哨的,但我得到了一堆错误:

/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====

任何人都可以告诉我什么是投票警告和未引用的问题? THX

2 个答案:

答案 0 :(得分:0)

由于某些函数在使用之前未声明,因此编译器假定隐式函数声明的返回类型为int。但是,int不能隐式地转换为指针,这在大多数情况下也没有意义。

您还必须在product_new中为product_finalizeproduct.h添加声明。

答案 1 :(得分:0)

您的代码示例存在各种问题。

您似乎正在使用C ++编译器编译此C代码;不要,使用C编译器。

你在打电话:

bar = g_object_new (...);

之前:

bar = product_new (...);

会泄漏第一个实例。

你也在调用product_finalize(),这是一个静态函数 - 这就是你得到编译错误的原因。

finalize()实例上的最后一个引用被删除时,将调用GObject实现;你不应该自己打电话。而是使用g_object_unref()删除对象实例的引用。