Jump to content
  • Advertisement
Sign in to follow this  
3ddreams

Can I use CALLBACK functions in class ?

This topic is 4870 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

I have a class like below. When I define EnumJoysticksCallback function out from class everythins is ok but When I define EnumJoysticksCallback function in class "g_pDI->EnumDevices( DI8DEVCLASS_GAMECTRL,EnumJoysticksCallback,NULL, DIEDFL_ATTACHEDONLY )" function not accept this function and I am getting this error "...error C2664: 'IDirectInput8A::EnumDevices' : cannot convert parameter 2 from 'BOOL (const DIDEVICEINSTANCE *,void *)' to 'LPDIENUMDEVICESCALLBACKA'" I am trying to insert callback function in class. Can I use callback functions as a class member? Is this possible? Thanks.

class CBT_INPUT
{
private:
	HINSTANCE  g_hinst;
	HRESULT         hr; 
	LPDIRECTINPUT8       g_pDI;
	LPDIRECTINPUTDEVICE8 g_pKeyboard,g_pMouse,g_pJoystick;	
public:
	...
        HRESULT InitInput(HWND hWnd,bool bExclusive,bool bForeground,bool bWinkeys);
	BOOL CALLBACK EnumJoysticksCallback( const DIDEVICEINSTANCE* 
pdidInstance, VOID* pContext );
        ...

}

////////////////////////////////////////////////////////////////////

HRESULT CBT_INPUT::InitInput(HWND hWnd,bool bExclusive,bool bForeground,bool bWinkeys){
        ...
	if( FAILED( hr = g_pDI->EnumDevices( DI8DEVCLASS_GAMECTRL,EnumJoysticksCallback,NULL, DIEDFL_ATTACHEDONLY ) ) ){
		return hr;
	}
        ...
}




[Edited by - 3ddreams on November 21, 2005 12:24:00 PM]

Share this post


Link to post
Share on other sites
Advertisement
As replied you can't do exactly what you are trying to do. I notice you are using DX. If you look at the samples (IIRC, it's in the common directory that all the samples refer to for their window class) you can see how MS worked around the problem.

Share this post


Link to post
Share on other sites
I solved problem by using static. Thanks SiCrane and another frends. But I have an anoter problem. When I declare g_pDI and g_pJoystick out from class program working. When declarated in class I am getting this error from in EnumJoysticksCallback :

.. error C2227: left of '->CreateDevice' must point to class/struct/union
.. error C2597: illegal reference to non-static member 'CBT_INPUT::g_pJoystick'

I looked C2597 error from MSDN. It says To access the nonstatic member, you must create an instance of the class and use a member-access operator (. or ->). If I do this g_pDI and g_pJoystick variables doesn't initialize and program will generete error.

CBT_INPUT test; //No compile error but program generate error and terminate
test.g_pDI->CreateDevice( pdidInstance->guidInstance, &test.g_pJoystick, NULL );

If I can't declare g_pDI and g_pJoystick variables in class I can't declare multi objects because every object will use same variables(g_pDI,g_pJoystick). I can't get out from this job. I need HELP. My c++ and english knowledge not enough.




//BTInput.h BEGIN

class CBT_INPUT{
private:
HINSTANCE g_hinst;
HRESULT hr;

LPDIRECTINPUT8 g_pDI;

LPDIRECTINPUTDEVICE8 g_pKeyboard,
g_pMouse,
g_pJoystick;

static BOOL CALLBACK EnumJoysticksCallback( const DIDEVICEINSTANCE* pdidInstance, VOID* pContext );
static BOOL CALLBACK EnumObjectsCallback( const DIDEVICEOBJECTINSTANCE* pdidoi, VOID* pContext );
...
}

// BTInput.h END


//BTnput.cpp BEGIN

BOOL CALLBACK CBT_INPUT::EnumJoysticksCallback( const DIDEVICEINSTANCE* pdidInstance,VOID* pContext ){
HRESULT hr;
//ERROR C2227,C2597
-> hr = g_pDI->CreateDevice( pdidInstance->guidInstance, &g_pJoystick, NULL );
if( FAILED(hr) ) return DIENUM_CONTINUE;

return DIENUM_STOP;
}
.....
//BTnput.cpp END




Share this post


Link to post
Share on other sites
Quote:
Original post by eastcoastsurfer
As replied you can't do exactly what you are trying to do. I notice you are using DX. If you look at the samples (IIRC, it's in the common directory that all the samples refer to for their window class) you can see how MS worked around the problem.


I am trying to write an input class. It done. But some variables generate errors when I use their in class. If I solve this problem input class comletely will done. In SDK samples callback functions not declarated in class but I tryed to use their in class. At this moment callback problem solved but variable problem continue. I wrote this problem above before this post.

Share this post


Link to post
Share on other sites
Okay, the important part: there is a HUGE difference between regular member functions and static functions. Hence there are two totally different kinds of function pointers and as the callbacks require global or static functions you won't have a this pointer and can't access anything but other static data (let's call them pseudo global).

So, unless you can either make the data your callback requires static as well or find a way to forward the changes you are pretty much stuck.

One rather ugly way comes to mind. Add a static pointer to an instance to your class. There shouldn't be much point in having more than one actual object reacting to input, even though it would be possible this way.

ie. something like this

class C {
static C* instance;
static void callback() {
if (!instance) return;
instance->bla;
instance->whatever=something;
}

void bla() {}
int whatever;
};

C* C::instance=0;



Now obviously whenever you create the object that should handle the input you need to do either
instance=this;
in it's constructor (doesn't sound to useful), in some kind of setAsInstance() function or just do
C object;
C::instance=&object;

Share this post


Link to post
Share on other sites
My problem shortly same as following.


struct VERTEX{
float x,y,z;
};

typedef VERTEX *LPVERTEX;

class FOO
{
public:
static void Test();
LPVERTEX a;

};

void FOO::Test(){

a->x=100.0f; //error C2227: left of '->x' must point to class/struct/union
printf("%f",a->x);//error C2227:..
}

int _tmain(int argc, _TCHAR* argv[])
{
FOO fo;
fo.Test();
return 0;
}



Share this post


Link to post
Share on other sites
Hi,

this is an elegant solution i use; it works for me - and a lot of people
It looks confusing, but its really simple.


Firstly, you create the static member function to use in the call back, as you have done :)
You only need to specify the callback as static... nothing else.


Second, set the callback function from within your class, and pass it the static EnumJoysticksCallback function (as i assume you have done already).
AND, where you have NULL, pass the class pointer (this)!

e.g.

// Note the 'this' pointer, casted to void*
g_pDI->EnumDevices( DI8DEVCLASS_GAMECTRL,EnumJoysticksCallback,(void*)this,
DIEDFL_ATTACHEDONLY )"



Third, now from within your static callback function, you can access the class member variables through the the class pointer; this is how you get around the inability to access non-static member functions and variables.

eg:


static whatever CBT_INPUT::EnumJoysticksCallback(const DIDEVICEINSTANCE* pdidInstance, VOID* pContext)
{
// pContext is (or should be) the 'this' parameter you passed in
// to the EnumDevices, it is of type 'void' and needs to be cast to
// a CBT_INPUT pointer
CBT_INPUT* ptr = (CBT_INPUT*)pContext;

//
// Now, Access you member functions like this, it works for private
// members as well!
//
ptr->g_hinst;
ptr->g_pDI;
// etc etc
}



you will notice alot of APIs that allow you to specify a callback function, will have a void* parameter.... this is what its mostly used for (im my experience)

Hope it works :)
Paul


Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

GameDev.net is your game development community. Create an account for your GameDev Portfolio and participate in the largest developer community in the games industry.

Sign me up!