473,230 Members | 1,493 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,230 software developers and data experts.

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 1958
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 thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

3
by: Jim | last post by:
I have a windows application that is accessing unmanaged code and providing a callback function that will create events at unknown time spans. When the EventHandler (callback function) fires it...
8
by: jody.florian | last post by:
Hi, I'm trying to use preg_replace_callback within a method. The preg_replace_callback() & mycallback() pair will only be used by this method, and this method will probably only be called once...
7
by: Kirk McDonald | last post by:
Let's say I have a function that takes a callback function as a parameter, and uses it to describe an iteration: def func(callback): for i in : callback(i) For the sake of argument, assume...
4
by: Kyku | last post by:
Hello all, I'm in a process of writing a small Linux C++ program for discovering repeaded files over a filesystem. One part of this task is traversing a directory structure. This is done by the...
22
by: SQACSharp | last post by:
I'm trying to get the control name of an editbox in another window. The following code set the value "MyPassword" in the password EditBox but it fail to return the control name of the EditBox. ...
4
by: pbd22 | last post by:
Hi. I have an ajax question. I am wondering if it is possible to get the response from a method within a given page, and that function alone? Traditionally, I have been getting the response...
11
by: lakshmiram.saikia | last post by:
Hi, I need to do the following operation : '" I have two mac addresses, say X and Y,where X is the base mac address, and Y is the nth mac address from X, each incremented by one. Now,I want...
3
by: Nashirak | last post by:
I am trying to implement callbacks in C++. I am modeling my callbacks after some of the stuff that was done in wxWidgets (if anyone is familiar with that). The syntax is as follows: // Header...
5
by: Jef Driesen | last post by:
I have a C DLL that I want to use from a C# project. The C header file contains these declarations: typedef void (*callback_t) (const unsigned char *data, unsigned int size, void *userdata);...
0
by: VivesProcSPL | last post by:
Obviously, one of the original purposes of SQL is to make data query processing easy. The language uses many English-like terms and syntax in an effort to make it easy to learn, particularly for...
3
isladogs
by: isladogs | last post by:
The next Access Europe meeting will be on Wednesday 3 Jan 2024 starting at 18:00 UK time (6PM UTC) and finishing at about 19:15 (7.15PM). For other local times, please check World Time Buddy In...
0
by: jianzs | last post by:
Introduction Cloud-native applications are conventionally identified as those designed and nurtured on cloud infrastructure. Such applications, rooted in cloud technologies, skillfully benefit from...
2
isladogs
by: isladogs | last post by:
The next Access Europe meeting will be on Wednesday 7 Feb 2024 starting at 18:00 UK time (6PM UTC) and finishing at about 19:30 (7.30PM). In this month's session, the creator of the excellent VBE...
1
by: davi5007 | last post by:
Hi, Basically, I am trying to automate a field named TraceabilityNo into a web page from an access form. I've got the serial held in the variable strSearchString. How can I get this into the...
0
by: MeoLessi9 | last post by:
I have VirtualBox installed on Windows 11 and now I would like to install Kali on a virtual machine. However, on the official website, I see two options: "Installer images" and "Virtual machines"....
0
by: DolphinDB | last post by:
Tired of spending countless mintues downsampling your data? Look no further! In this article, you’ll learn how to efficiently downsample 6.48 billion high-frequency records to 61 million...
0
by: Aftab Ahmad | last post by:
Hello Experts! I have written a code in MS Access for a cmd called "WhatsApp Message" to open WhatsApp using that very code but the problem is that it gives a popup message everytime I clicked on...
0
by: Aftab Ahmad | last post by:
So, I have written a code for a cmd called "Send WhatsApp Message" to open and send WhatsApp messaage. The code is given below. Dim IE As Object Set IE =...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.