Sign in to follow this  
The Forgotten Mindset

void* to functor casting???

Recommended Posts

Hey guys, I've got a little function pointer conversion problem. Here's a simplified version of what I'm doing:
// Game Phase Funtors
int		(*DoIntro)();
int		(*DoFrame)();
int		(*DoOutro)();

int SetFlag(int ID, void *value)
{
	switch( ID )
	{	
		case FLAG_FRAMEFUNC:
			DoFrame = (???)value;	// how do I cast this?
			break;
		case FLAG_TITLETEXT:
			m_TitleText = (char*)value;
                        break;
	}
	return 0;
}

int MyFrameFunction()
{
	Render();
	Input();
	Update();
	
	return 0;
}

int WinMain()
{
	SetFlag(FLAG_FRAMEFUNC, MyFrameFunction);
	return 0;
}




Alright, I know there are other ways of doing this, but I like this approach the best. And I don't think switches are that bad either [smile]. PS: Does anyone know how to change the win32 titlebar text at runtime? [help] [Edited by - The Forgotten Mindset on June 29, 2005 9:20:00 PM]

Share this post


Link to post
Share on other sites
Verg    450
[EDIT - removed reinterpret_cast example]

You can change the title bar as soon as you have a window handle-- maybe when processing WM_ACTIVATEAPP;


SetWindowText(HWND,LPCTSTR);

Share this post


Link to post
Share on other sites
smart_idiot    1298
Example, calling value as a function taking no arguments and returning void: (*(void(*)(void))value)();

Beware that function pointers aren't guarenteed to be the same size as data pointers in cause you care about portability. As an example:

void (*function)(void) = reinterpret_cast<void(*)(void)>(pointer);

This gives me 'error: ISO C++ forbids casting between pointer-to-function and pointer-to-object' when compiling with GCC.

Share this post


Link to post
Share on other sites
Thanks, I'll give it a try. I'm confused now :/ I'm not used to this kind of c++. I've used function pointers before, but not like this.

But the SetWindowText function didn't work for me for some reason, and it was the correct window handle. Oh, I don't think my screen was updating.

Share this post


Link to post
Share on other sites
Verg    450
From MSDN:


The SetWindowText function changes the text of the specified window's title bar
(if it has one). If the specified window is a control, the text of the control is
changed. However, SetWindowText cannot change the text of a control in another
application.

BOOL SetWindowText(
HWND hWnd, // handle to window or control
LPCTSTR lpString // address of string
);



Sorry, don't know what to say [smile]

Share this post


Link to post
Share on other sites
smr    2468
What type is DoFrame? If value is a function pointer, then your function signature is wrong:

int SetFlag(int ID, void (*lpfn)())

Share this post


Link to post
Share on other sites
smr    2468
Quote:
Original post by smr
What type is DoFrame? If value is a function pointer, then your function signature is wrong:

int SetFlag(int ID, int (*lpfn)())

Share this post


Link to post
Share on other sites
Roboguy    794
Try:

typedef int (*Functor)();

Functor doIntro;
Functor doFrame;
Functor doOutro;

// ...
doFrame = reinterpret_cast<Functor>(value);

Share this post


Link to post
Share on other sites
Programmer16    2321
A simple solution to this is:

class Value
{
public:
LPCTSTR m_lpszString;
int m_iInteger;
bool m_bBoolean;
int (*m_fpIntFunc)();

Value(const char* pString) : m_lpszString(pString){}
Value(int iInteger) : m_iInteger(iInteger){}
Value(bool bBoolean) : m_bBoolean(bBoolean){}
Value(int (*fpIntFunc) : m_fpIntFunc(fpIntFunc){}
};

int (*DoIntro)();
int (*DoFrame)();
int (*DoOutro)();
std::string m_Title;
//etc
int SetFlag(int iID, Value Flag)
{
switch(iID)
{
case FLAG_FRAMEFUNC:
{
DoIntro = Flag.m_fpIntFunc;
break;
}
case FLAG_TITLETEXT:
{
m_Title = Flag.m_lpszString;
break;
}
}
return 0;
}

Share this post


Link to post
Share on other sites
Thanks Programmer16, that looks good. I could probably just copy/paste that [grin]

But Roboguy suggested to me over #gamedev that I should try templates:

template<typename Type>
int SetFlag(int ID, Type value) {
switch (ID) {
case FLAG_FRAMEFUNC:
DoFrame = value;
// ...
}
}



In effect, I think this is pretty much the same thing as your code, just less of it. Mabey your version is more high performance :)

Share this post


Link to post
Share on other sites
Programmer16    2321
I've tried templates before and I get errors (for my different switch, saying that it can't convert from blah to blahblah, even though that case isn't being used.) This might be my dinosaur compiler (MSVC++6), I'm not sure. Either way, hope you get it working!

Share this post


Link to post
Share on other sites
FlowingOoze    236
Quote:
Original post by The Forgotten Mindset
Hey guys, I've got a little function pointer conversion problem. Here's a simplified version of what I'm doing:

*** Source Snippet Removed ***

Alright, I know there are other ways of doing this, but I like this approach the best. And I don't think switches are that bad either [smile].

PS: Does anyone know how to change the win32 titlebar text at runtime? [help]


What exactly are you trying to do? Why can't you just override SetFlags() for different types or better yet, use entirely different functions to set different attributes. Ie. SetFrameFunction() for frame functions and SetWindowTitle() for window titles and so on. There are most likely much better ways of doing what you're trying to do. In C++ there is rarely a need to use function pointers at all, since virtual methods are often better suited for the job. (Functors or function objects are a different matter entirely.)

Share this post


Link to post
Share on other sites
Yes! Thanks vallentin that's exactly what I was looking for! It works now!

And to answer your question FlowingOoze, I was using functions like SetFrameFunc(), but I like this approach better. It allows every single command to be processed in one central function. But overloading that function would have been a good choice too. Thanks :).

Rating++es for all! [smile]

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this