Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > comp.lang.c > #17383 > unrolled thread

Call Backs

Started byEdward Rutherford <edward.p.rutherford79@REMOVETHIS.gmail.com>
First post2012-02-15 19:33 +0000
Last post2012-02-17 21:58 +0000
Articles 11 — 9 participants

Back to article view | Back to comp.lang.c


Contents

  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

#17383 — Call Backs

FromEdward Rutherford <edward.p.rutherford79@REMOVETHIS.gmail.com>
Date2012-02-15 19:33 +0000
SubjectCall 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]


#17384

Fromtom st denis <tom@iahu.ca>
Date2012-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]


#17388

FromJames Kuyper <jameskuyper@verizon.net>
Date2012-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]


#17394

FromDevil with the China Blue Dress <chine.bleu@yahoo.com>
Date2012-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]


#17428

FromNick Keighley <nick_keighley_nospam@hotmail.com>
Date2012-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]


#17392

FromLew Pitcher <lpitcher@teksavvy.com>
Date2012-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]


#17393

FromDevil with the China Blue Dress <chine.bleu@yahoo.com>
Date2012-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]


#17412

FromMalcolm McLean <malcolm.mclean5@btinternet.com>
Date2012-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]


#17417

FromShao Miller <sha0.miller@gmail.com>
Date2012-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]


#17418

FromShao Miller <sha0.miller@gmail.com>
Date2012-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]


#17536

FromWillem <willem@toad.stack.nl>
Date2012-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