3

I'm trying to use g_idle_add() with function that needs multiple arguments. Can I pass them just inline somehow or do I have to create a structure for this?

The main goal is to reduce memory consumption, everything else is secondary.

static gboolean checker(gpointer plugin, int toggle){
    ...  
    return FALSE;
}
g_idle_add(checker, ??? plugin, 0 ??? );
int_ua
  • 1,646
  • 2
  • 18
  • 32
  • 1
    `typedef void* gpointer;` *An untyped pointer. gpointer looks better and is easier to use than void*.* Yuck... – this Dec 20 '13 at 02:01
  • Can you elaborate on the inline? – this Dec 20 '13 at 02:40
  • Maybe not exactly inline. Without creating a dedicated `struct`. I wouldn't like increasing memory consumption. – int_ua Dec 20 '13 at 02:49
  • You can create a struct on the stack and pass it's address. Just make sure the struct doesn't go out of scope(global, static...). – this Dec 20 '13 at 02:56
  • Edited the question with link to the code. I don't yet know how to create it on the stack, can you please add the code? – int_ua Dec 20 '13 at 02:59
  • I don't think the line 43 is right since the seconde parametre is a pointer. I think you just call the function this way `g_idle_add((GsourceFunc)checker, (gpointer)plugin, (gpointer)0);` (you have to cast the arguments) – rullof Dec 20 '13 at 03:15
  • Have to do it one by one right? – Fiddling Bits Dec 20 '13 at 03:19
  • **rullof**, I'm not sure it worked. Without enclosing arguments in parentheses it's `too few arguments` and with them there are only `warning: left-hand operand of comma expression has no effect`. Not sure if that will work as I expect. I've actually taken these parentheses from my Python knowledge, I'm beginner in C. – int_ua Dec 20 '13 at 03:26
  • 2
    You have to create a structure. Passing more than one user_data argument won't work. – ptomato Dec 20 '13 at 03:52

1 Answers1

3

The function you pass to g_idle_add needs to have a signature matching the GSourceFunc type, which means it has to take exactly one pointer argument. You'll have to allocate a structure on the heap (NOT the stack as a commenter has suggested, that will only be valid for as long as the function creating it runs) containing the information you need. Something like this:

struct checker_arguments {
    gpointer plugin;
    int toggle;
};

static gboolean checker(gpointer data) {
    struct checker_arguments *args = data;
    /* Do stuff with args->plugin and args->toggle */
    g_slice_free1(args, sizeof(*args));
    return FALSE;
}

struct checker_arguments *args = g_slice_alloc(sizeof(*args));
args->plugin = plugin;
args->toggle = 0;
g_idle_add(checker, args);

Because you're concerned with memory consumption, I used slice allocation in this example rather than the normal heap allocation. Slice allocation is more efficient for objects of fixed size.

Esme Povirk
  • 3,004
  • 16
  • 24
  • instead of g_slice_alloc/g_slice_free1, use g_slice_new() and g_slice_free() with the type you're allocating. it's easier to read, and clearer. – ebassi Dec 20 '13 at 09:19