Re: communicating through callback

From: Peter Slootweg (peter.slootweg_at_xtxexlxuxs.xnxext)
Date: 07/20/04


Date: Tue, 20 Jul 2004 17:26:07 GMT


"andthen" <a@n.d> wrote in message
news:CGQJc.4567$Iz2.1479616@news4.srv.hcvlny.cv.net...
> I'm using a windows library function which does not return anything useful
> (EnumWindows... returns a BOOL), I give it a pointer to a callback
function
> and it sends the data I want to the callback function. My question is,
what
> is the best way to get that data into the initial function, which called
the
> library function? The only way I can think of is to have the callback
> function modify a global variable and then have the initial function
access
> that. But that seems messy and I'm wondering if there is a better way. Any
> ideas?
>
>
the nice way to implement callbacks is to allow the caller to pass in a
context pointer that is then passed into the callback function

e.g.

/* from handle.h */
typedef unsigned long handle;
#define handleisvalid(h) (h!=0UL)
typedef int (*cbfunctype)(handle h, void * context);
int enumhandles(cbfunctype cbfunc, void * context);

/* from x.c */
#include "handle.h"
#include <stdio.h>
struct indata
   {
   int i;
   };

struct outdata
   {
   int o;
   };

struct cbcontextdata {
   struct indata in;
   struct outdata out;
   };

int mycbfunc(handle h, void *context)
   {
   cbdata * pcbd = context;
   pcbd->out.o += pcbd->in.i + pcbd->in.i ; /* or whatever else you want to
do with h */
   return !0; /* 0 if you want to stop processing */
   }

int main(void)
    {
    int rc;
    cbdata cbd;
    cbd.in.i = 1;
    cbd.out.o = 0;
    rc = enumhandles(mycbfunc,&cbd);
    if (rc != 0)
         {
         printf("%d\n",cbd.out.o);
         }
    return 0;
    }

/* from handle.c */
#include "handle.h"
int enumhandles(cbfunctype cbfunc, void * context)
    {
    handle somehandle;
    int rc = 1;
    somehandle = /* firsthandle() */ 100;
    while(handleisvalid(somehandle) && ((*cbfunc)(somehandle,context) != 0))
         somehandle = /* nexthandle() */ somehandle - 1;
    return rc;
    }

[OT]
EnumWindows has a context parameter of type LPARAM - which is large enough
to hold a void pointer.
e.g.
EnumWindows(mywinenumcallback,(LPARAM)(void *)&mycallbackdata);
IMHO They really should have done it as a LPVOID (void *).
[/OT]



Relevant Pages

  • Re: function pointer help!
    ... //the return void and input prameters are defined in the manual... ... void MyProjectView::CallHandler(int,unsigned int, unsigned int, void*) ... You are attempting to use a C++ member function as the callback, but the callback is defined in terms or C, not C++. ... The underlying problem is that C++ functions receive a hidden parameter, the 'this' pointer, so their signature is incompatible with C definitions. ...
    (microsoft.public.vc.mfc)
  • RE: Callback not being called
    ... The callback in the unmanaged code appears to fire, ... ppStringArray, int cArray); ... void CALLBACK TimerProc( ... theCallBack,LPTSTR* ppStringArray, int cArray) ...
    (microsoft.public.dotnet.framework.interop)
  • [RFC 2/3] qla2xxx: Enable 2xxx series LLD target mode support
    ... This patch enables target mode support with the qla2xxx SCSI LLD using ... +extern int ... * @ha: HA context ... +static void ...
    (Linux-Kernel)
  • Re: Passing an integer to a function that accepts a void pointer
    ... int main{ ... callback of a library I can't change and the prototype of the callback ... is well defined by the library to accept void pointer. ...
    (comp.lang.c)
  • Re: Passing an integer to a function that accepts a void pointer
    ... int main{ ... For the cast to void*: ... callback of a library I can't change and the prototype of the callback ... Just create an object containing the value 10, and then pass a pointer ...
    (comp.lang.c)