Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations strongm on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

pointer to a function type

Status
Not open for further replies.

0x4B47

Programmer
Jun 22, 2003
60
US
Can someone please tell me in what type of a situation a variable of the following type might be used?

Code:
typedef void (* pFoo)( void * lpsomeData );

Are there any other ways of achieving the same results? If so, what are the pros and cons of the alternatives?

Thanks in advance.

01001011 01000111
 
>Can someone please tell me in what type of a situation a variable of the following type might be used?

For example as a callback.

>Are there any other ways of achieving the same results?

Yes. In the world of object oriented programming we use a similar concept of functions together with classes and call them 'virtual methods', which is one of the cornerstones of C++.

>If so, what are the pros and cons of the alternatives?

Using virtual methods is a whole lot easier and more flexible than using function pointers (not to mention the entire OO concept). But you can achieve pretty much the same, though funcptrs are a less elegant IMHO.

Ie instead of supplying a function a funcptr that it can call back (without knowing any details other than the function's signature), in OO you supply the function a pointer (or reference) to a class that declares some (possibly virtual) method the function can call back (without knowing any details other than the class' interface).

/Per
[sub]
"It was a work of art, flawless, sublime. A triumph equaled only by its monumental failure."[/sub]
 
pFoo is defined to be a type for declaring a pointer to a function, that returns nothing, and takes a void pointer as parameter.

Another example...
This is the prototype of qsort declared in stdlib.h...
Code:
void qsort( void *base, size_t num, size_t width, int (__cdecl *compare )(const void *elem1, const void *elem2 ) );

it could also have been expressed like this...
Code:
typedef int (__cdecl *PFNCOMPARE)(const void*, const void*);

void qsort(void *base, size_t num, size_t width, PFNCOMPARE compare);

you could sort an array of long-types using qsort like this...

Code:
#define ARRAY_LENGTH 10

int cbfnc_compare_long(const void* e1, const void* e2)
{
	return ( (*(long *)e1) < (*(long *)e2) ) ? 1 : 0;
}

long long_array[ARRAY_LENGTH] = { 1886, 2398, 6548, 5466, 1234, 4321, 1597, 5324, 9843, 9591 };

qsort(long_array, ARRAY_LENGTH, sizeof(long), cbfnc_compare_long);


Recently I have build a little API, called TREE, build arround a structure type TREE, that needs to callback the caller sometimes when traversing the tree.
I have defined both a C-style and a C++ way of calling back the caller to pass each node in the tree together with the data supplied...

Code:
class I_TREETRAVERSE{
public:
	virtual BYTE TreeTraverse(TREE* pNode, DWORD dwAppCmd, DWORD dwAppData, long lAppData)=0;
};
typedef BYTE (* TREETRAVERSE)(TREE* pNode, DWORD dwAppCmd, DWORD dwAppData, long lAppData);

And this is what the caller calls to start the traversal, one of these overloaded functions depending on what callback pointer is passed...
Code:
BYTE tree_tt_outward(TREE* pTree, DWORD dwAppCmd, DWORD dwAppData, long lAppData, I_TREETRAVERSE* pItt)
{
	BYTE bContinue;

	//Callback caller with current node + supplied appdata
	bContinue = pItt->TreeTraverse(pTree, dwAppCmd, dwAppData, lAppData);

	//Caller got what he needs and cancels traversal
	if(!bContinue)return 0;

	//code to traverse recursively through the tree nodes...
	...
	...
}
// or
BYTE tree_tt_outward(TREE* pTree, DWORD dwAppCmd, DWORD dwAppData, long lAppData, TREETRAVERSE TreeTraverse)
{
	BYTE bContinue;

	//Callback caller with current node + supplied appdata
	bContinue = TreeTraverse(pTree, dwAppCmd, dwAppData, lAppData);

	//Caller got what he needs and cancels traversal
	if(!bContinue)return 0;

	//code to traverse recursively through the tree nodes...
	...
	...
}

I_TREETRAVERSE is an abstract class because it contains at least one pure virtual function, one that has no implementation. Any class derived from this class must override and implement the method. The nice thing is that any class derived from I_TREETRAVERSE can pass its this-pointer to tree_tt_outward through(I_TREETRAVERSE* pItt). In turn tree_tt_outward can only see method TreeTraverse through pointer pItt.


Binaryshi.

 
One useful thing that can be done with function pointers is, for example, the emulation of another processor. Group similar instructions together and use function pointers (and a few other things) and make "jump tables" for emulating the instruction set. You might look at which implements this.
 
I use function pointers when testing a class that has many Set and Get functions with the same signature. I create a function that accepts a function pointer and tries to break it by passing NULL pointers, invalid data... to that function pointer to see if it handles it gracefully.
This makes my code much smaller, easier to manage and more readable.
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top