Click to See Complete Forum and Search --> : Question about function pointers


MrDoomMaster
November 29th, 2004, 05:21 PM
I'm trying to create a typedef which can create a function pointer to a function which returns void and has no parameters, such as the example delcaration you see below:

void TestFunc(void);

I've tried the following:

typedef void (*_FuncPtr)(void);

So, if I do this:


_FuncPtr FunctionPtr = TestFunc;

FunctionPtr();


The compiler returns an error saying that FunctionPtr does not evaluate to a function taking 0 arguments.

How would I appropriately create a function pointer such as this?

Thanks!

MrViggy
November 29th, 2004, 05:32 PM
I think the proper way to use a function pointer, to call the function that it is pointing to, is:
(*FunctionPtr)();
Viggy

MrDoomMaster
November 29th, 2004, 06:42 PM
Viggy,

I tried your suggested calling method, and my compiler returned the following error:

error C2171: '*' : illegal on operands of type 'thu::_ThreadProc'


Here is more code for your reference:


namespace thu
{
/* Typedefs */
typedef void (*_ThreadProc)(void);
};

Kheun
November 29th, 2004, 06:59 PM
MrDoomMaster, I can't see anything wrong with your code, your example actually works on VC6. Probably, it has something wrong with your definition of TestFunc().


#include <stdio.h>

void TestFunc(void)
{
printf("TestFunc\n");
}

typedef void (*_FuncPtr)(void);

int main()
{
_FuncPtr FunctionPtr = TestFunc;
FunctionPtr();

return 0;
}

MrDoomMaster
November 29th, 2004, 07:13 PM
Well, maybe it will help if I post all of my code.

It's not much, it's just a class I've created which makes creating threads a little simpler. I haven't had the chance to test it yet due to this compiler error, but perhaps it will give you a better chance of finding what I'm doing wrong. This class is contained in a Header file and CPP file:

First, my Header File:

//=========================================================================
//=========================================================================
// Multithreading Utilities Library (Thread_Utils)
//
// Author: Robert Dailey (MrDoomMaster)
//
//=========================================================================
//=========================================================================

#ifndef _THREAD_UTILS_
#define _THREAD_UTILS_

//--Includes---------------------------------------------------------------
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
#include <windows.h>

//-------------------------------------------------------------------------



//=============================================================================================
// Namespaces
//=============================================================================================
/*
||
*/

namespace thu
{
/* Typedefs */
typedef void (*_ThreadProc)(void);
};

//=============================================================================================



//=============================================================================================
// Classes
//=============================================================================================
/*
|| This class provides the entire functionality of this library. It supports safe
|| multithreading.
*/
class Thread_Utils
{
private:
//--Variables-----------------------------------------------------------
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
bool ThreadRunning ;
DWORD ThreadID ;
HANDLE ThreadHandle ;
HANDLE StopHandle ;
HANDLE WaitHandle ;
thu::_ThreadProc ThreadCode ;
//----------------------------------------------------------------------


//--Prototypes----------------------------------------------------------
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
static DWORD WINAPI EntryPoint(LPVOID pThis);
//----------------------------------------------------------------------

public:
//--Prototypes----------------------------------------------------------
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/*--Constructors/Destructors--*/
Thread_Utils(thu::_ThreadProc ThreadFunction);
virtual ~Thread_Utils();

/*--Functions--*/
void StartThread(void);
void StopThread(void);
//virtual void ThreadCode(void);
//----------------------------------------------------------------------
};

//=============================================================================================

#endif


And my CPP file:


//=========================================================================
//=========================================================================
// Multithreading Utilities Library (Thread_Utils)
//
// Author: Robert Dailey (MrDoomMaster)
//
//=========================================================================
//=========================================================================

#include "Thread_Utils.h"


//===========================================================================================
// Function Definitions
//===========================================================================================
/*
|| // TODO: Provide descriptions for all functions
*/
DWORD WINAPI Thread_Utils::EntryPoint(LPVOID pThis)
{
while(true)
{
if(::WaitForSingleObject(((Thread_Utils*)pThis)->StopHandle, 0) == WAIT_OBJECT_0)
{
::SetEvent(((Thread_Utils*)pThis)->WaitHandle);
::ExitThread(0);
}

ThreadCode();
}
}

//===========================================================================================
/*
||
*/
Thread_Utils::Thread_Utils(thu::_ThreadProc ThreadFunction)
{
ThreadHandle = NULL;
StopHandle = NULL;
WaitHandle = NULL;
ThreadID = 0;
ThreadCode = ThreadFunction;
}

//===========================================================================================
/*
||
*/
Thread_Utils::~Thread_Utils(void)
{
if(ThreadHandle)
StopThread();
}

//===========================================================================================
/*
||
*/
void Thread_Utils::StartThread(void)
{
StopHandle = ::CreateEvent(NULL, TRUE, FALSE, NULL);
WaitHandle = ::CreateEvent(NULL, TRUE, FALSE, NULL);
ThreadHandle = ::CreateThread(NULL, 0, EntryPoint, this, 0, &ThreadID);
}

//===========================================================================================
/*
||
*/
void Thread_Utils::StopThread(void)
{
::SetEvent(StopHandle);

::WaitForSingleObject(WaitHandle, INFINITE);

::CloseHandle(StopHandle);
::CloseHandle(WaitHandle);
::CloseHandle(ThreadHandle);

StopHandle = NULL;
WaitHandle = NULL;
ThreadHandle = NULL;
}

//===========================================================================================

//===========================================================================================

//===========================================================================================

//===========================================================================================

//===========================================================================================

//===========================================================================================

//===========================================================================================

//===========================================================================================

//===========================================================================================

//===========================================================================================


I have bolded parts of my code which relate to the issue at hand, for your convenience. Thank you for your time, I hope my code isn't too rough to navigate!

Kheun
November 29th, 2004, 07:37 PM
You have made a small mistake in your static function. Your static function doesn't have the this pointer for invoking the function pointer. You need to invoke the it using pThis.

DWORD WINAPI Thread_Utils::EntryPoint(LPVOID pThis)
{
while(true)
{
if(::WaitForSingleObject(((Thread_Utils*)pThis)->StopHandle, 0) == WAIT_OBJECT_0)
{
::SetEvent(((Thread_Utils*)pThis)->WaitHandle);
::ExitThread(0);
}

((Thread_Utils*)pThis)->ThreadCode(); // this pointer isn't available in the static funciton.
}
}

MrDoomMaster
November 29th, 2004, 09:25 PM
Wow, thanks! I always miss stupid little things like that

Andreas Masur
November 30th, 2004, 02:57 AM
error C2171: '*' : illegal on operands of type 'thu::_ThreadProc'
Well...that is simply because 'ThreadProc()' is a class member function. There is a difference between function pointers to global and to class member functions...

HuangRG
December 2nd, 2004, 02:41 AM
Your TestFunc is class member function? if yes, write to following:
static void TestFunc()
{
.......
}

_uj
December 2nd, 2004, 03:17 AM
I think the proper way to use a function pointer, to call the function that it is pointing to, is:
(*FunctionPtr)();
Viggy
Also have a look at the "smart" pointers at Boost and Loki.