Re: No data available at callback



On 29 June 2017 at 15:36, William A oswald <wildbillo comcast net> wrote:
First a top level scenario. I am writing an interface application for a flat
bed scanner which will result in the use of the gdk function
g_signal_connect. I decided to pass some data to my callback function since
it would simplify some of the logic. However, to my surprise I found that
the callback function received a data pointer of zero (0). This is a sure
fire why of getting a segmentation fault. I fine it hard to believe that
their would be a bug with function which leads me to believe I am not using
the function correctly.

Indeed.

Now some details:
I am running a Fedora 22 distribution that has a gtk3-3.16 and glib2-2.14
versions.

You are running on a Linux distribution that was End-of-Life'd in July
2016; the version of GTK+ is two years old, and that cannot clearly be
the version of GLib you're using, since it'd be more than 9 years old.
You're likely using GLib 2.44.

It is not a deal breaker that I use the data option of the function, but I
would be nice to know why this is happening in my case.

The source code involved is as follows:
CallBkData dummy, *datapt;
datapt = &dummy;

You're creating a pointer to a stack-allocated variable...

  datapt->optNum = opt_source;
  datapt->whatever = 6794;
  sigID = g_signal_connect(G_OBJECT(combo), "changed",
                            G_CALLBACK(cs_source_callback),
                            (void *)datapt);

... and passing it to a function that may be called at any random
point outside of the function scope.

You're only getting NULL because the compiler is clearly trying to be
helpful, instead of just passing you garbage pointers.

Any insight would be appreciated.

The data you pass to a signal callback must be valid in the scope of
the callback. This is achieved either by passing a pointer to a
variable that is in a scope larger than both the function that calls
g_signal_connect() *and* the callback itself. Generally, this is
achieved through a global variable.

Alternatively, you need to allocate the data on the heap, e.g.:

    // g_new0() is safe against overflows, and zero-fills the returned
allocation
    CallBkData *data = g_new0 (CallBkData, 1);

    data->optNum = opt_source;
    data->whatever = 6794;

    // No need to cast the first argument; no need to cast the data argument
    sigID = g_signal_connect (combo, "changed", G_CALLBACK
(cs_source_callback), data);

If the callback is supposed to live as long as the application, that's
all you need; if you're going to disconnect the signal handler, then
you'll have to keep a pointer to the data so you can free it and avoid
leaking.

Ciao,
 Emmanuele.

-- 
https://www.bassi.io
[@] ebassi [@gmail.com]


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