469,945 Members | 1,349 Online
Bytes | Developer Community
New Post

Home Posts Topics Members FAQ

Post your question to a community of 469,945 developers. It's quick & easy.

need addititional arg in given callback

Hi,

in a given library I register callback functions with this function:

bool set_callback(int index, int (*callback_function)(long));

I need the callback function to also pass the index which is, however,
not (re-)passed by the callback function.

Normally, I would just register callback functions for each
index I need if the amount of callback functions was known at design
time... But it isn't.

Could someone help me find the right approach to solve that problem?

Felix
Nov 14 '05 #1
15 1780
Felix Kater <f.******@gmx.net> wrote:
in a given library I register callback functions with this function:

bool set_callback(int index, int (*callback_function)(long));

I need the callback function to also pass the index which is, however,
not (re-)passed by the callback function.

Normally, I would just register callback functions for each
index I need if the amount of callback functions was known at design
time... But it isn't.

Could someone help me find the right approach to solve that problem?


It's a quandary. You'd like closures for something like this, but you
don't have those in C. A quick and dirty hack would be to use a
file-scope (i.e., global, or if at all possible, file-local) variable,
possibly with the aid of a helper function if you can't change the
callback function itself.

Richard
Nov 14 '05 #2
rl*@hoekstra-uitgeverij.nl (Richard Bos) wrote:
A quick and dirty hack would be to use a
file-scope (i.e., global, or if at all possible, file-local) variable,
possibly with the aid of a helper function


Good to hear that there's a way, however, could you elaborate that a
bit to me?

Felix
Nov 14 '05 #3
Felix Kater <f.******@gmx.net> writes:
in a given library I register callback functions with this function:

bool set_callback(int index, int (*callback_function)(long));

I need the callback function to also pass the index which is, however,
not (re-)passed by the callback function.

Normally, I would just register callback functions for each
index I need if the amount of callback functions was known at design
time... But it isn't.


If you can't change the type of the argument passed to the callback
function, you could make its argument an index into a data structure
from which it can retrieve as much information as you care to provide.

The simplest such data structure, of course, is an array (presumably
of structs or of pointers to structs). If you don't know in advance
how many elements you'll need, allocate it dynamically and use
realloc() as needed to expand it.

--
Keith Thompson (The_Other_Keith) ks***@mib.org <http://www.ghoti.net/~kst>
San Diego Supercomputer Center <*> <http://users.sdsc.edu/~kst>
We must do something. This is something. Therefore, we must do this.
Nov 14 '05 #4
Keith Thompson <ks***@mib.org> wrote:
If you can't change the type of the argument passed to the callback
function, you could make its argument an index into a data structure


I'm afraid I didn't get the point:

a. I can't re-use the long arg from the callback function as a pointer
since this value (which is passed) has nothing to do with the index
value I need inside the callback function and which I pass to the
register function.

b. If you ment to make an array of function pointers: How would I fill
that with meaningfull pointers to functions which I would have to hard
code anyway?

Felix
Nov 14 '05 #5
Felix Kater <f.******@gmx.net> writes:
Keith Thompson <ks***@mib.org> wrote:
If you can't change the type of the argument passed to the callback
function, you could make its argument an index into a data structure


I'm afraid I didn't get the point:

a. I can't re-use the long arg from the callback function as a pointer
since this value (which is passed) has nothing to do with the index
value I need inside the callback function and which I pass to the
register function.

[snip]

Sorry, I think I misunderstood the problem (I don't often use callback
functions). I was thinking you could control the long value passed to
the callback function, but obviously it's called by the library in a
manner you can't control.

The library provides:

bool set_callback(int index, int (*callback_function)(long));

What does the long argument represent?

(There may not be a good way to do what you want.)

--
Keith Thompson (The_Other_Keith) ks***@mib.org <http://www.ghoti.net/~kst>
San Diego Supercomputer Center <*> <http://users.sdsc.edu/~kst>
We must do something. This is something. Therefore, we must do this.
Nov 14 '05 #6
Felix Kater wrote:

in a given library I register callback functions with this
function:

bool set_callback(int index, int (*callback_function)(long));

I need the callback function to also pass the index which is,
however, not (re-)passed by the callback function.

Normally, I would just register callback functions for each
index I need if the amount of callback functions was known at
design time... But it isn't.

Could someone help me find the right approach to solve that
problem?


This has nothing to do with the portable standard C language, but
deals with your particular system and installation. So find a
newsgroup that deals with that system.

--
Chuck F (cb********@yahoo.com) (cb********@worldnet.att.net)
Available for consulting/temporary embedded and systems.
<http://cbfalconer.home.att.net> USE worldnet address!

Nov 14 '05 #7
CBFalconer <cb********@yahoo.com> writes:
Felix Kater wrote:
in a given library I register callback functions with this
function:

bool set_callback(int index, int (*callback_function)(long));

I need the callback function to also pass the index which is,
however, not (re-)passed by the callback function.

Normally, I would just register callback functions for each
index I need if the amount of callback functions was known at
design time... But it isn't.

Could someone help me find the right approach to solve that
problem?


This has nothing to do with the portable standard C language, but
deals with your particular system and installation. So find a
newsgroup that deals with that system.


I don't agree that the question is necessarily off-topic. He's using
a particular system-specific library, and details about the workings
of that library would certainly be off-topic, but there have already
been several responses about possible solutions that depend only on
the set_callback declaration he's shown us.

It may turn out that the *solution* is either system-specific (and
therefore off-topic) or nonexistent.

--
Keith Thompson (The_Other_Keith) ks***@mib.org <http://www.ghoti.net/~kst>
San Diego Supercomputer Center <*> <http://users.sdsc.edu/~kst>
We must do something. This is something. Therefore, we must do this.
Nov 14 '05 #8
Keith Thompson <ks***@mib.org> wrote:
It may turn out that the *solution* is either system-specific (and
therefore off-topic) or nonexistent.


The more I ask people about that problem the more I believe there is no
clean solution: Since the only distinguishing information between the
callback functions the client programmer gets are the function pointers
itself I can only register different functions -- and, as I don't know
how many there will be necessary I don't see any way to do that in advance.

Felix
Nov 14 '05 #9
Felix Kater wrote:
in a given library I register callback functions with this function:

bool set_callback(int index, int (*callback_function)(long));
Did you write this function?
What is the index argument used for?
I need the callback function to also pass the index
which is, however, not (re-)passed by the callback function.
What do you mean here?
Your *set_callback* function passes index
but your *callback* function does not?
Normally, I would just register callback functions
for each index [that] I need
if the [number] of callback functions was known at design time...
But it isn't.

Could someone help me find the right approach to solve that problem?


What problem?
Try to elaborate a little more.
Show us an example.
Nov 14 '05 #10
Felix Kater <f.******@gmx.net> wrote:
rl*@hoekstra-uitgeverij.nl (Richard Bos) wrote:
A quick and dirty hack would be to use a
file-scope (i.e., global, or if at all possible, file-local) variable,
possibly with the aid of a helper function


Good to hear that there's a way, however, could you elaborate that a
bit to me?


AFAICT, what you want is something like this:

int callback(long index)
{
return some_lookup[index];
}

which you can set up with

set_callback(&callback, some_index);

and should then be called by the surrounding code (probably a library or
the OS API) like this:

callback(index);

whereas what this code actually does is this:

callback();

and you're required to set things up using

set_callback(&callback);

with no provision for passing in the required index.

Is that impression of what you want right? If not, I'm sorry, I
misunderstood what you want. If it is, though, you could do this
instead:

long public_index;

int callback_helper(void)
{
return callback(public_index);
}

public_index=some_index;
set_callback(&callback_helper);

so that a call to the callback function will result in

callback_helper();

which will fetch the index you wanted, and then call the original
callback function with that value.

Richard
Nov 14 '05 #11
"E. Robert Tisdale" <E.**************@jpl.nasa.gov> wrote:
bool set_callback(int index, int (*callback_function)(long));
Did you write this function?


No, and I can't change it.

What is the index argument used for?


It's used for the logic inside the library. Think of a simple
assignment which hardware event is bound to what callback.
If this index was passed to/by the callback as an argument I would be
done...

I need the callback function to also pass the index
which is, however, not (re-)passed by the callback function.


What do you mean here?
Your *set_callback* function passes index
but your *callback* function does not?


Exactly. If the callback would pass the index I could just use one
callback function for all indexes and check the index what to do.
Without that I have to create callback functions for each index. That's
the problem...

More and more I think there is no general way out of this dilemma. I'll
try to contact the distributor of the libraray and ask if they could
pass the index argument with the next release.

Felix
Nov 14 '05 #12
rl*@hoekstra-uitgeverij.nl (Richard Bos) wrote:
Is that impression of what you want right? If not, I'm sorry, I
misunderstood what you want. If it is, though, you could do this
instead:

long public_index;

int callback_helper(void)
{
return callback(public_index);
}

public_index=some_index;
set_callback(&callback_helper);

so that a call to the callback function will result in

callback_helper();

which will fetch the index you wanted, and then call the original
callback function with that value.

Thanks for that, Richard.
You didn't misunderstand me.

I realize now, however, that I didn't mention the fact clearly that I
have to register more than one callback function in the beginning
(rather than set and unset them) which will then be called at any time
in any order. So, I don't know when to set the public_index.

Felix
Nov 14 '05 #13
Felix Kater <f.******@gmx.net> wrote:
rl*@hoekstra-uitgeverij.nl (Richard Bos) wrote:
Is that impression of what you want right? If not, I'm sorry, I
misunderstood what you want. If it is, though, you could do this
instead:

long public_index;

int callback_helper(void)
{
return callback(public_index);
}

public_index=some_index;
set_callback(&callback_helper);

so that a call to the callback function will result in

callback_helper();

which will fetch the index you wanted, and then call the original
callback function with that value.


Thanks for that, Richard.
You didn't misunderstand me.

I realize now, however, that I didn't mention the fact clearly that I
have to register more than one callback function in the beginning
(rather than set and unset them) which will then be called at any time
in any order. So, I don't know when to set the public_index.


O-kay... so in effect, you cannot even do this:

public_index=index1;
function_which_will_call_your_callback();

... more code...

public_index=index2;
function_which_will_call_your_callback();

and so forth, because the function will need to be called
asynchronously, behind your back? In that case, I'm afraid I don't know
a solution, either.

Richard
Nov 14 '05 #14
Felix Kater wrote:

in a given library I register callback functions with this function:

bool set_callback(int index, int (*callback_function)(long));

I need the callback function to also pass the index which is, however, not (re-)passed by the callback function.
Why do you _need_ the index?
Normally, I would just register callback functions for each
index I need if the amount of callback functions was known at
design time... But it isn't.

Could someone help me find the right approach to solve that problem?


The right approach is make your callback functions independant of
the index, or to persuade the library writers to redesign their
callback interface.

A kludge though is something like the code below. You make your
callback functions take the int parameter (A, B and C below),
and put a wrapper around the the set_callback function...

#include <stdio.h>
#include <stdlib.h>

typedef int wrapper_f(long);
typedef int callback_f(int, long);

#define countof(x) (sizeof(x) / sizeof *(x))

#define blank
#define semicolon ;
#define comma ,

/* specify the indexes to wrap with this macro */
#define the_indexes(M,_) \
M( 1) _ \
M( 2) _ \
M( 7) _ \
M(12) _ \
M(42)

struct wt_element_t
{
const int index;
wrapper_f * const wrapper;
callback_f *callback;
};

struct wt_element_t wrapper_table[];

#define as_enums(I) wrapper_ ## I ## _e
#define as_initialisors(I) { I, wrapper_ ## I, 0 }

#define as_function_declarations(I) \
int wrapper_ ## I (long)

#define as_function_definitions(I) \
int wrapper_ ## I (long n) \
{ \
return wrapper_table[wrapper_ ## I ## _e]. \
callback(I, n); \
}

enum my_wrapper_enums { the_indexes(as_enums, comma) };
the_indexes(as_function_declarations, semicolon);

/* put these in a single source file */

the_indexes(as_function_definitions, blank)

struct wt_element_t wrapper_table[] =
{ the_indexes(as_initialisors, comma) };

int set_callback_wrapper(int index, callback_f *callback)
{
size_t i;
for (i = 0; i < countof(wrapper_table); i++)
if (wrapper_table[i].index == index)
{
wrapper_table[i].callback = callback;
/* install the wrapper callback function */
/* set_callback(index, wrapper_table[i].wrapper); */
return 1;
}
return 0;
}

/* sample usage */

/* your callback functions */
int A(int i, long n) { return printf("A(%2d, %3ld)\n", i, n); }
int B(int i, long n) { return printf("B(%2d, %3ld)\n", i, n); }
int C(int i, long n) { return printf("C(%2d, %3ld)\n", i, n); }

int main(void)
{
long n;

/* install callbacks */
set_callback_wrapper( 1, A);
set_callback_wrapper( 2, B);
set_callback_wrapper(12, C);
set_callback_wrapper(42, A);

/* simulate 20 pseudo random callbacks */
for (n = 1; n <= 20; n++)
{
size_t i = rand() % countof(wrapper_table);
while (wrapper_table[i].callback == 0)
i = (i + 1) % countof(wrapper_table);
wrapper_table[i].wrapper(n);
}

return 0;
}

--
Peter

Nov 14 '05 #15
rl*@hoekstra-uitgeverij.nl (Richard Bos) wrote:
because the function will need to be called
asynchronously, behind your back? In that case, I'm afraid I don't know
a solution, either.


Unfortunatelly, yes. Thanks again.

Felix
Nov 14 '05 #16

This discussion thread is closed

Replies have been disabled for this discussion.

Similar topics

7 posts views Thread by Kirk McDonald | last post: by
4 posts views Thread by Kyku | last post: by
11 posts views Thread by lakshmiram.saikia | last post: by
3 posts views Thread by Nashirak | last post: by
5 posts views Thread by Jef Driesen | last post: by
By using this site, you agree to our Privacy Policy and Terms of Use.