views:

279

answers:

8

This:

typedef HRESULT (*PFN_HANDLE)(ClassName&);

It's used like this:

DWORD ClassName::Wait(PFN_HANDLE pfnh_foo)
{
  while (!done) {
    waitCode = WaitForMultipleObjects(paramA, paramB, paramC, paramD)

    if (waitCode == WAIT_OBJECT_0)
    {
      pfnh_foo(*this);
    }
    else
      done;
  }
  return waitCode;
}

It appears that Wait does nothing except block when it gets to WaitForMultipleObjects and then after that does this strange pfnh_foo thing and either loops back around to wait again or exits

+7  A: 

Your wait() function basically waits for multiple objects and then invoke function using function pointer PFN_HANDLE if the wait is successful ( indicated by return value WAIT_OBJECT_0).

pfnh_foo(*this);

This calls the function pointed by pfnh_foo with argument *this.

Lets say we have function:

HRESULT someFunction(ClassName& myClassInstance)
{
//blah .. blah
}

Wait will be invoked like this:

PFN_HANDLE pfnh_foo = &someFunction;  //function pointer to someFunction
wait(pfnh_foo);
aJ
someFunction is the function pointer, so PFN_HANDLE pfnh_foo = someFunction; wait(pfnh_foo); or just wait(someFunction)
Joakim Elofsson
PFN_HANDLE pfnh_foo = PFN_HANDLE pfnh_foo = someFunction; Both are fine :)
aJ
+2  A: 

pfnh_foo is a function pointer - it's running a function, with your class as a parameter

Paul Betts
So I could just call the function directly and remove the the argument to Wait altogether. Right?
No - the argument to Wait is a function pointer. Unless the argument to Wait is always the same function pointer, you need it.
sean e
Or to reword that: yes, you could remove the argument to Wait if Wait is always called with the same parameter. The argument to Wait tells you signature of the function it is expecting, but you might have multiple functions with the same signature. It is not a given that there is only one function ever passed to Wait.
sean e
Maybe a nice example for function pointers is the qsort() function: it takes a function pointer to a compare function. That way you can sort any type of data, you just need to provide a function that compares two items of your data and tells which one is "bigger" than the other.
bluebrother
+2  A: 

WAIT_OBJECT_0 is the first handle you're waiting for, if it is it executes pfnh_foo, for any other wait handle it exits.

Otávio Décio
+2  A: 

It's defining a function pointer to a function with the prototype:

HRESULT someFunction(ClassName &)

It's then taking the function that's passed in and calling it using the current object as the parameter.

Eric
+2  A: 

pfnh_foo is a function pointer. You can use functions like normal variables.

typedef HRESULT (*PFN_HANDLE)(ClassName&) means that PFN_HANDLE is a pointer to a function of signature:

HRESULT foo(ClassName&)

Tadeusz A. Kadłubowski
+2  A: 

This is thread sync code.
Looks to me like ClassName:Wait is running in a separate thread and waiting for one of the specified objects to signal that it's free before calling the callback
It's being used to avoid a race condition

zebrabox
+2  A: 

This is a mutual exlcusion mechanism, or a means to cooperate between competing for resources... thus the need to "wait" for the objects.

edit: Wikipedia has a good intro on mutual exclusion and touches on some foundational issues, algorithms, and data structures. If you are new to mutual exclusion principles, it's worth a read.

http://en.wikipedia.org/wiki/Mutual_exclusion

San Jacinto
A: 

So i could just remove the function pointer and call the function directly at that point. It would only make sense to use a function pointer if there were more than one function that would need to handle whatever object is signled when the WaitforMulitpleObject returns in Wait().

ie.

HRESULT Foo(ClassName& myClass);
HRESULT Bar(ClassName& myClass);

anotherFunction(...)
{
  Wait(Foo);
  Wiat(Bar);
}
Yes, that is correct.
sean e