Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > comp.lang.c > #17383 > unrolled thread
| Started by | Edward Rutherford <edward.p.rutherford79@REMOVETHIS.gmail.com> |
|---|---|
| First post | 2012-02-15 19:33 +0000 |
| Last post | 2012-02-17 21:58 +0000 |
| Articles | 11 — 9 participants |
Back to article view | Back to comp.lang.c
Call Backs Edward Rutherford <edward.p.rutherford79@REMOVETHIS.gmail.com> - 2012-02-15 19:33 +0000
Re: Call Backs tom st denis <tom@iahu.ca> - 2012-02-15 11:36 -0800
Re: Call Backs James Kuyper <jameskuyper@verizon.net> - 2012-02-15 15:02 -0500
Re: Call Backs Devil with the China Blue Dress <chine.bleu@yahoo.com> - 2012-02-15 12:27 -0800
Re: Call Backs Nick Keighley <nick_keighley_nospam@hotmail.com> - 2012-02-16 02:56 -0800
Re: Call Backs Lew Pitcher <lpitcher@teksavvy.com> - 2012-02-15 15:20 -0500
Re: Call Backs Devil with the China Blue Dress <chine.bleu@yahoo.com> - 2012-02-15 12:24 -0800
Re: Call Backs Malcolm McLean <malcolm.mclean5@btinternet.com> - 2012-02-15 16:02 -0800
Re: Call Backs Shao Miller <sha0.miller@gmail.com> - 2012-02-16 01:21 -0500
Re: Call Backs Shao Miller <sha0.miller@gmail.com> - 2012-02-16 01:25 -0500
Re: Call Backs Willem <willem@toad.stack.nl> - 2012-02-17 21:58 +0000
| From | Edward Rutherford <edward.p.rutherford79@REMOVETHIS.gmail.com> |
|---|---|
| Date | 2012-02-15 19:33 +0000 |
| Subject | Call Backs |
| Message-ID | <jhh1aj$43c$1@speranza.aioe.org> |
I've read plenty of discussion about callback functions as used in C (ie in qsort). I'm comfortable with this: really it is a function pointer. What I'm not sure about is how (or if) a callback differs to events like GUI's use. One of the things I found about events, at least in a VB6 project I did, is that an event can be broadcast to all objects and they can use it if desired (code only and GUI objects). Each object has to have a receive function for that event though. The only way I can see to do event broadcasting with a callback is to have a special callback that in turn calls a list of receiver functions that would be in each module. For example, a timer that broadcasts a time tick every second would call a function (for example) Timer_1min(void) that in turn would call functions in all of the modules that need to know the time. I've also thought about a message que, but that is begining to sound like too much work. Is there a better way? Thanks for any helpful information.
[toc] | [next] | [standalone]
| From | tom st denis <tom@iahu.ca> |
|---|---|
| Date | 2012-02-15 11:36 -0800 |
| Message-ID | <f48a9273-ed8e-4a03-989e-238eb39c45d0@gr6g2000vbb.googlegroups.com> |
| In reply to | #17383 |
On Feb 15, 2:33 pm, Edward Rutherford <edward.p.rutherfor...@REMOVETHIS.gmail.com> wrote: > I've read plenty of discussion about callback functions as used in C (ie > in qsort). I'm comfortable with this: really it is a > function pointer. What I'm not sure about is how (or if) a > callback differs to events like GUI's use. One of the things I > found about events, at least in a VB6 project I did, is that an event > can be broadcast to all objects and they can use it if desired (code > only and GUI objects). Each object has to have a receive function for > that event though. > > The only way I can see to do event broadcasting with a callback is to > have a special callback that in turn calls a list of receiver functions > that would be in each module. For example, a timer that broadcasts a > time tick every second would call a function (for example) > Timer_1min(void) that in turn would call functions in all of the modules > that need to know the time. I've also thought about a message que, but > that is begining to sound like too much work. Is there a better way? > > Thanks for any helpful information. Dude, C doesn't have "objects" ... qsort() calls your callback [to compare items] while it's running from your operating context. Remember C is [more or less] a single-serial task programming language [C11 adds threading...]. So it's not like qsort() is running in the background, and it's certainly not calling an "object"'s callback method.
[toc] | [prev] | [next] | [standalone]
| From | James Kuyper <jameskuyper@verizon.net> |
|---|---|
| Date | 2012-02-15 15:02 -0500 |
| Message-ID | <jhh31f$kt1$2@dont-email.me> |
| In reply to | #17384 |
On 02/15/2012 02:36 PM, tom st denis wrote: ... > Dude, C doesn't have "objects" ... The C standard defines what an "object" is in 3.15; the concept is very important in C. It's just not the same concept as the one you're thinking of. -- James Kuyper
[toc] | [prev] | [next] | [standalone]
| From | Devil with the China Blue Dress <chine.bleu@yahoo.com> |
|---|---|
| Date | 2012-02-15 12:27 -0800 |
| Message-ID | <chine.bleu-8130A4.12271815022012@news.eternal-september.org> |
| In reply to | #17384 |
In article <f48a9273-ed8e-4a03-989e-238eb39c45d0@gr6g2000vbb.googlegroups.com>, tom st denis <tom@iahu.ca> wrote: > On Feb 15, 2:33 pm, Edward Rutherford > <edward.p.rutherfor...@REMOVETHIS.gmail.com> wrote: > > I've read plenty of discussion about callback functions as used in C (ie > > in qsort). I'm comfortable with this: really it is a > > function pointer. What I'm not sure about is how (or if) a > > callback differs to events like GUI's use. One of the things I > > found about events, at least in a VB6 project I did, is that an event > > can be broadcast to all objects and they can use it if desired (code > > only and GUI objects). Each object has to have a receive function for > > that event though. > > > > The only way I can see to do event broadcasting with a callback is to > > have a special callback that in turn calls a list of receiver functions > > that would be in each module. For example, a timer that broadcasts a > > time tick every second would call a function (for example) > > Timer_1min(void) that in turn would call functions in all of the modules > > that need to know the time. I've also thought about a message que, but > > that is begining to sound like too much work. Is there a better way? > > > > Thanks for any helpful information. > > Dude, C doesn't have "objects" ... 'object' is a generic term that can refer to a package of data and sometimes code. If you define a struct and call that an object in your code, then your C code does have objects. -- My name Indigo Montoya. | It's Coraline, not Caroline. You flamed my father. | I'm whoever you want me to be. Prepare to be spanked. | Annoying Usenet one post at a time. Stop posting that! | At least I can stay in character.
[toc] | [prev] | [next] | [standalone]
| From | Nick Keighley <nick_keighley_nospam@hotmail.com> |
|---|---|
| Date | 2012-02-16 02:56 -0800 |
| Message-ID | <a8eb17b9-2ea9-49c8-b23b-f7d22a64c1b3@t15g2000yqi.googlegroups.com> |
| In reply to | #17384 |
On Feb 15, 7:36 pm, tom st denis <t...@iahu.ca> wrote: > On Feb 15, 2:33 pm, Edward Rutherford > <edward.p.rutherfor...@REMOVETHIS.gmail.com> wrote: > > I've read plenty of discussion about callback functions as used in C (ie > > in qsort). I'm comfortable with this: really it is a > > function pointer. not sure what "really" contributes... > > What I'm not sure about is how (or if) a > > callback differs to events like GUI's use. probably depends on the GUI but a function pointer used as a callback is a common way to do it. Windows commonly uses a giant switch statement. > > One of the things I > > found about events, at least in a VB6 project I did, is that an event > > can be broadcast to all objects and they can use it if desired (code > > only and GUI objects). Each object has to have a receive function for > > that event though. > > > The only way I can see to do event broadcasting with a callback is to > > have a special callback that in turn calls a list of receiver functions > > that would be in each module. For example, a timer that broadcasts a > > time tick every second would call a function (for example) > > Timer_1min(void) that in turn would call functions in all of the modules > > that need to know the time. I've also thought about a message que[ue], but > > that is begining to sound like too much work. Is there a better way? a message queue is the common way to deal with. come on a queue isn't that much work! > > Thanks for any helpful information. > > Dude, never sure what that word means or adds to the debate. > C doesn't have "objects" ... he didn't say it did. he said VB did. C may not have objects (in your sense) but you can implement OO GUIs in it (eg. Windows, X-Window). > qsort() calls your callback [to compare items] while it's running from > your operating context. Remember C is [more or less] a single-serial > task programming language [C11 adds threading...]. so what? > So it's not like > qsort() is running in the background, and it's certainly not calling > an "object"'s callback method. that anyone suggested this is an invention of yours
[toc] | [prev] | [next] | [standalone]
| From | Lew Pitcher <lpitcher@teksavvy.com> |
|---|---|
| Date | 2012-02-15 15:20 -0500 |
| Message-ID | <jsU_q.113$Bn4.47@newsfe21.iad> |
| In reply to | #17383 |
On Wednesday 15 February 2012 14:33, in comp.lang.c, edward.p.rutherford79@REMOVETHIS.gmail.com wrote: > I've read plenty of discussion about callback functions as used in C (ie > in qsort). [snip] > The only way I can see to do event broadcasting with a callback is to [snip] One way (doable in Standard C) would be to create /two/ functions, one to register a callback for an event, and the other to call all callbacks on the occurrence of the event. Call the first function registerCallback(), and model it on the existing atexit() or on_exit() functions, so that the caller provides the function with the address of the function to be called when the event occurs. The function would simply record the callback function address in a suitable, self maintained and externally available list, and do nothing else. Call the second function eventHappened(), and model it on the "at exit" behaviour of the existing exit() function, in that it simply runs the list created by the first function, calling each callback in turn. Now, to the intended use: Each component that wants to know about an event calls the registerCallback() function, giving it /that component's/ function to intercept the event. Te component that actually initiates the event calls eventHappened(), which calls each registered callback. Voila, a subscription-model event broadcaster. > I've also thought about a message que, but > that is begining to sound like too much work. And, also off topic for comp.lang.c. The use of a message queue is something that standard C knows nothing about. It is part of the operating environment, not the C language. (Some environments don't have message queues). > Is there a better way? Probably. Especially if you look to environment-specific solutions like message queues, semaphores (standard in C11?), and other in-process communications techniques. -- Lew Pitcher
[toc] | [prev] | [next] | [standalone]
| From | Devil with the China Blue Dress <chine.bleu@yahoo.com> |
|---|---|
| Date | 2012-02-15 12:24 -0800 |
| Message-ID | <chine.bleu-7077E9.12244615022012@news.eternal-september.org> |
| In reply to | #17383 |
In article <jhh1aj$43c$1@speranza.aioe.org>, Edward Rutherford <edward.p.rutherford79@REMOVETHIS.gmail.com> wrote: > I've read plenty of discussion about callback functions as used in C (ie > in qsort). I'm comfortable with this: really it is a > function pointer. What I'm not sure about is how (or if) a > callback differs to events like GUI's use. One of the things I Event functions are callbacks which are function addresses. (On some systems an interrupt called routine is marked and compiled differently, but those should no longer appear in GUIs.) 'event' is a vague term, but what happens is the GUI develops some information, usually packaged in a struct, that it can then deliver back to the program using the GUI. The GUI can allow the program to define event handlers which are a callback function and possibly additional information. These event handlers can be packaged into structs which are linked are within linked structures created by the GUI. The GUI knows how to traverse its structures to deliver the event information to the program's event handler. > found about events, at least in a VB6 project I did, is that an event > can be broadcast to all objects and they can use it if desired (code > only and GUI objects). Each object has to have a receive function for > that event though. The GUI will know how to traverse its representation of the objects to find each callback that needs to be called. > The only way I can see to do event broadcasting with a callback is to > have a special callback that in turn calls a list of receiver functions > that would be in each module. For example, a timer that broadcasts a > time tick every second would call a function (for example) I have some code that does like this. The program calls a library function with the address of a function with the correct prototype and context information. The library puts this on a linked list from a static variable. At a tick it then traverses the linked list, calling each function with its context information. The native closure of C function is just the static and global variables in its environment; this means if you want to pass information from one callback function to another using just functions, you have to use a static/global variable. That is why more interfaces include a context value that callback functions can use to communicate through an auto variable or heap block. -- My name Indigo Montoya. | It's Coraline, not Caroline. You flamed my father. | I'm whoever you want me to be. Prepare to be spanked. | Annoying Usenet one post at a time. Stop posting that! | At least I can stay in character.
[toc] | [prev] | [next] | [standalone]
| From | Malcolm McLean <malcolm.mclean5@btinternet.com> |
|---|---|
| Date | 2012-02-15 16:02 -0800 |
| Message-ID | <d545e87f-92ce-44b4-96eb-4730784258e1@gr6g2000vbb.googlegroups.com> |
| In reply to | #17383 |
On Feb 15, 7:33 pm, Edward Rutherford <edward.p.rutherfor...@REMOVETHIS.gmail.com> wrote: > > The only way I can see to do event broadcasting with a callback is to > have a special callback that in turn calls a list of receiver functions > that would be in each module. For example, a timer that broadcasts a > time tick every second would call a function (for example) > Timer_1min(void) that in turn would call functions in all of the modules > that need to know the time. I've also thought about a message que, but > that is begining to sound like too much work. Is there a better way? > Bascially you do this. You set up tick() so that it's called by the timer, maybe as an interrupt function. You then have a global list of function pointers. tick() calls every function pointer on the list. You have a routine to add a fucntion pointer to the list, or to delete one. Of course you can then add bells and whistles. You can have function pointers that are called only once, ones that are passed data, ones that are only called every so often. You've got to decide how your program is going to be structured. If you have lots of events it probably makes sense to build some sort of message queue and to have a generic "event" structure to pass information to standardised callback routines. If all you've got is one timer, this is probably overkill. The main secret is to always pass a user-supplied pointer back to the callback. That allows the user to tag callbacks with dynamic data, and means that he can have an arbitrary number of objects registered with the same callback routine. -- MiniBasic - how to write a script interpreter http://www.malcolmmclean.site11.com/www
[toc] | [prev] | [next] | [standalone]
| From | Shao Miller <sha0.miller@gmail.com> |
|---|---|
| Date | 2012-02-16 01:21 -0500 |
| Message-ID | <jhi72t$3pc$1@dont-email.me> |
| In reply to | #17383 |
On 2/15/2012 14:33, Edward Rutherford wrote:
> I've read plenty of discussion about callback functions as used in C (ie
> in qsort). I'm comfortable with this: really it is a
> function pointer. What I'm not sure about is how (or if) a
> callback differs to events like GUI's use. One of the things I
> found about events, at least in a VB6 project I did, is that an event
> can be broadcast to all objects and they can use it if desired (code
> only and GUI objects). Each object has to have a receive function for
> that event though.
>
> The only way I can see to do event broadcasting with a callback is to
> have a special callback that in turn calls a list of receiver functions
> that would be in each module. For example, a timer that broadcasts a
> time tick every second would call a function (for example)
> Timer_1min(void) that in turn would call functions in all of the modules
> that need to know the time. I've also thought about a message que, but
> that is begining to sound like too much work. Is there a better way?
You can 'typedef' a function type:
typedef int f_click(struct s_clickable *);
Then a function pointer to that type of function might be:
f_click * click;
So you might have:
struct s_clickable {
f_click * click;
};
struct s_button {
struct s_clickable clickable;
const char * caption;
};
Then, where you might have 'Sub Command1_Click' in Microsoft Visual
Basic, in C, you might do:
/* Declare using 'f_click' to ensure the type */
static f_click cmdbtn1_click;
/* Definition */
static int cmdbtn1_click(struct s_clickable * clickable) {
unsigned char * ptr;
struct s_button * button;
/*
* Non-standard 'container_of' and 'CONTAINING_RECORD'
* do something like this, but usually without the 'ptr'
* intermediary
*/
ptr = (void *) clickable;
ptr -= offsetof(struct s_button, clickable);
button = (void *) ptr;
printf("You pressed %s!\n", button->caption);
return 0;
}
struct s_button cmdbtn1 = {
/* clickable */
{ cmdbtn1_click },
/* caption */
"MyCommandButton1",
};
Then, as others have mentioned, you can have a "everything-clicked
event" and it can have a linked-list of subscribers. You can add
'&cmdbtn1.clickable' to that linked-list. The event can have an
associated function which walks the list and invokes
'list_item->clickable->click(&list_item->clickable)' for each item in
the list.
I hope this helps. :)
[toc] | [prev] | [next] | [standalone]
| From | Shao Miller <sha0.miller@gmail.com> |
|---|---|
| Date | 2012-02-16 01:25 -0500 |
| Message-ID | <jhi79q$4mc$1@dont-email.me> |
| In reply to | #17417 |
On 2/16/2012 01:21, Shao Miller wrote: > > Then, as others have mentioned, you can have a "everything-clicked > event" and it can have a linked-list of subscribers. You can add > '&cmdbtn1.clickable' to that linked-list. The event can have an > associated function which walks the list and invokes > 'list_item->clickable->click(&list_item->clickable)' for each item in > the list. Oops. I probably meant 'list_item->clickable->click(list_item->clickable)', since 'clickable' is presumably a pointer.
[toc] | [prev] | [next] | [standalone]
| From | Willem <willem@toad.stack.nl> |
|---|---|
| Date | 2012-02-17 21:58 +0000 |
| Message-ID | <slrnjjtjcv.129u.willem@toad.stack.nl> |
| In reply to | #17383 |
Edward Rutherford wrote:
) I've read plenty of discussion about callback functions as used in C (ie
) in qsort). I'm comfortable with this: really it is a
) function pointer. What I'm not sure about is how (or if) a
) callback differs to events like GUI's use. One of the things I
) found about events, at least in a VB6 project I did, is that an event
) can be broadcast to all objects and they can use it if desired (code
) only and GUI objects). Each object has to have a receive function for
) that event though.
)
) The only way I can see to do event broadcasting with a callback is to
) have a special callback that in turn calls a list of receiver functions
) that would be in each module.
No, the place that handles the events could just have a list of callback
pointers instead of just the one, and call each one in turn. That's
usually how it's done in other languages too.
) For example, a timer that broadcasts a
) time tick every second would call a function (for example)
) Timer_1min(void) that in turn would call functions in all of the modules
) that need to know the time. I've also thought about a message que, but
) that is begining to sound like too much work. Is there a better way?
A message queue? Those are only useful in multithreaded environments, to
send information from one thread to other(s).
What are you actually trying to accomplish?
SaSW, Willem
--
Disclaimer: I am in no way responsible for any of the statements
made in the above text. For all I know I might be
drugged or something..
No I'm not paranoid. You all think I'm paranoid, don't you !
#EOT
[toc] | [prev] | [standalone]
Back to top | Article view | comp.lang.c
csiph-web