Re: more news about a static member func declaration for a signal func



philip dahlquist wrote:
well, when i static-ized my signal function, it made it no possible to any other non-static
member functions or non-static data members.  the static declaration
solved one problem but created other problems.  are there any other
solutions to the signal function declaration problems?
should i re-post the code snippet?


When coding in C++, the GTK+ C callback functions must be either free functions or static member functions. They cannot be regular member functions. To do that requires some fancy code work, like libsigc2 does. Depending on your needs you have are two options. You could use one of the C++ language bindings for GTK+, there are several (http://www.gtk.org/bindings.html).

Otherwise, if your building a large application or reusable library and want to write your own C++ classes you can try something like the following. This code is similar to the code C++ langauage bindings use to hook into the GTK+ signal emission system.

In your base class contructor you need to store a C++ object's 'this' pointer inside the GTK+ C object that it wraps, so it can be retrieved from inside a static member function later:

// BaseClass

class BaseClass
{
private:
    GObject gobject_;
protected:
    gulong connect(const char *signal, GCallback callback);
public:
    BaseClass();
    virtual ~BaseClass();
};

BaseClass::BaseClass(GObject *gobject)
: gobject_(gobject)
{
    if (!g_object_get_data(gobject, "my_object"))
    {
        g_object_set_data(object, "my_object", this);
    }
}

You also need to remove the object's 'this' pointer:

BaseClass::~BaseClass()
{
    if (gobject_)
    {
        g_object_steal_data(gobject_, "my_object");
        g_object_unref(gobject_);
        gobject_ = 0;
    }
}

gulong
BaseClass::connect(const char *signal, GCallback callback)
{
        return g_signal_connect(gobject_, signal, callback, 0); 
}

// Button

class Button : public BaseClass
{
private:
    friend void clicked_callback(GtkButton *button, gpointer data);
    void clicked_callback(GtkButton *button, gpointer data);
protected:
    virtual void on_clicked();
public:
    Button();
    virtual ~Button();
};

Button::Button()
{
    connect("clicked", G_CALLBACK(&Button::clicked_callback));
}

Button::clicked_callback((GtkButton *button, gpointer data)
{
    void *ptr = g_object_get_data((GObject*)button, "my_object"));
    if (ptr)
        static_cast<Button*>(ptr)->on_clicked();
}

void
Button::on_clicked()
{
}

I haven't tested this code but I think it should work!

Jeff.








[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]