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.
codeguru.com
Copyright Internet.com Inc., All Rights Reserved.