[C++] Pointer to member problem

Started by
10 comments, last by n3Xus 15 years, 9 months ago
I'm following the directInput tutorial to setup joystick input and I'm stuck at one part. I have the direct input class (called DX_INPUT). In this class I have a function:
bool CALLBACK	EnumJoysticksCallback(DIDEVICEINSTANCE* pdidInstance, VOID* pContext);
I have to pass this function as a parameter here:
m_lpDI->EnumDevices(DI8DEVCLASS_GAMECTRL,&DX_INPUT::EnumJoysticksCallback ,NULL,DIEDFL_ATTACHEDONLY)
I've gone through some tutorials on pointer to memeber functions but I still can't get it to work. I get this error: Error 1 error C2664: 'IDirectInput8W::EnumDevices' : cannot convert parameter 2 from 'bool (__stdcall DX_INPUT::* )(DIDEVICEINSTANCE *,void *)' to 'LPDIENUMDEVICESCALLBACKW' help would be very appreciated :D
Advertisement
Cue Evil Steve....

[BAM]

P.S: Make the function a static member.
A member function pointer is not the same thing as a function pointer, which is what DIEnumDevicesCallback expects.

Edit: Also, I'm pretty sure return type is taken as part of the pointer to function type, in which case
bool (*)(DIDEVICEINSTANCE*, VOID*) is not a
BOOL (*)(DIDEVICEINSTANCE*, VOID*)
Quote:Original post by Driv3MeFar
A member function pointer is not the same thing as a function pointer, which is what DIEnumDevicesCallback expects.

Edit: Also, I'm pretty sure return type is taken as part of the pointer to function type, in which case
bool (*)(DIDEVICEINSTANCE*, VOID*) is not a
BOOL (*)(DIDEVICEINSTANCE*, VOID*)


You are correct, however that probably gets by the compile since it can implicitly cast it.
thx for the help so far but I still can't figure it out...

this is a part of the .h file that defines the CALLBACK function:

class DX_INPUT{......	// Callback function	BOOL CALLBACK EnumJoysticksCallback(DIDEVICEINSTANCE *pdidInstance, void *pContext);......	};



this is a part of the .cpp file:

........// The callback functionBOOL DX_INPUT::EnumJoysticksCallback(DIDEVICEINSTANCE *pdidInstance, void *pContext){	// Obtain the interface to the enumerated joystick	if(FAILED (m_lpDI->CreateDevice(pdidInstance->guidInstance,&m_pJoystick,NULL) ))	{		ONMESSAGE("cannont obtain joystick intefaces","error:dxinput");		return DIENUM_STOP;	}	return DIENUM_CONTINUE;}// In this function the EnumJoysticksCallback is passed as an paramter for m_lpDI->EnumDevices:void DX_INPUT::InitializeJoysticks(){		 m_lpDI->EnumDevices(DI8DEVCLASS_GAMECTRL, !CALLBACK_FUNCTION_GOES_HERE! ,NULL,DIEDFL_ATTACHEDONLY)}


can someone tell me what exactly do I need to change to get this working??
as Dave said: Make the function a static member:

static BOOL CALLBACK EnumJoysticksCallback(DIDEVICEINSTANCE *pdidInstance, void *pContext);
Quote:Original post by n3Xus
thx for the help so far but I still can't figure it out...

this is a part of the .h file that defines the CALLBACK function:

*** Source Snippet Removed ***


this is a part of the .cpp file:

*** Source Snippet Removed ***

can someone tell me what exactly do I need to change to get this working??
You can't pass a non-static function to a callback like that, so you need to make the function static. A member function has an implicit "this" pointer, which means that it's not the same as a free-standing function, so you can't pass it in as a function pointer.

Doing that means that you can't access any member variables from within the function though, since it doesn't have a "this" pointer. That's what the context parameter is for.

You want the following...

Header:
static BOOL CALLBACK EnumJoysticksCallback(DIDEVICEINSTANCE *pdidInstance, void *pContext);

Source file:
// The callback functionBOOL DX_INPUT::EnumJoysticksCallback(DIDEVICEINSTANCE *pdidInstance, void *pContext){   DX_INPUT* pThis = (DX_INPUT*)pContext;   // Obtain the interface to the enumerated joystick   if(FAILED (pThis->m_lpDI->CreateDevice(pdidInstance->guidInstance, pThis->&m_pJoystick, NULL) ))   {      ONMESSAGE("cannont obtain joystick intefaces","error:dxinput");      return DIENUM_STOP;   }   return DIENUM_CONTINUE;}// In this function the EnumJoysticksCallback is passed as an paramter for m_lpDI->EnumDevices:void DX_INPUT::InitializeJoysticks(){	   m_lpDI->EnumDevices(DI8DEVCLASS_GAMECTRL, EnumJoysticksCallback, this, DIEDFL_ATTACHEDONLY)}

That way, you pass in the "this" pointer as the context parameter to the callback function, then you grab it out and use it.
thx Steve, I saw that "this passing" in a tutorial but I didn't know I can use VOID* pContext to pass it :D
Quote:Original post by n3Xus
thx Steve, I saw that "this passing" in a tutorial but I didn't know I can use VOID* pContext to pass it :D
Yeah, it's fairly standard that any C-style callback function like this will take a void* "user context" parameter that you can use to communicate with the function. There's some exceptions of course, but every Win32 and DirectX callback I can think of allows this.

<offtopic>
Quote:Original post by Dave
Cue Evil Steve....

[BAM]

P.S: Make the function a static member.
I'm slow today - I'm ball deep in code at work [sad]
</offtopic>
damnit it still doesn't work :@ I'm gonna have nightmares because of this thing.
Now the problem is if I write:

m_lpDI->EnumDevices(DI8DEVCLASS_GAMECTRL, EnumJoysticksCallback ,this,DIEDFL_ATTACHEDONLY)

I get this error:
Error 1 error C2664: 'IDirectInput8W::EnumDevices' : cannot convert parameter 2 from 'BOOL (__stdcall *)(DIDEVICEINSTANCE *,void *)' to 'LPDIENUMDEVICESCALLBACKW'

If I write it like this:
m_lpDI->EnumDevices(DI8DEVCLASS_GAMECTRL, (LPDIENUMDEVICESCALLBACKW)EnumJoysticksCallback ,this,DIEDFL_ATTACHEDONLY)

it compiles but the function doesn't get exectuted (m_pJoystick remains NULL and I also put a Beep(,) in it and it doesn't beep. So yet again I ask for your assistance

This topic is closed to new replies.

Advertisement