Is there a way to create a function pointer in one class and have it point to a function in another class?
I keep getting the error that the right side of the equality is (__cdecl)<func_name>(params)
For instance:
Code:
class A
{
public:
void Func(int x) {};
};
class Object
{
A AInstance;
public:
Object(void);
void (A::*Func)(int x);
};
Object::Object(void)
{
Func=AInstance.Func;
}
This is a stupid example but what I have is a sound engine that is attached to the main CD3DApp object via a pointer. Instead of creating a function in CD3DApp for the corresponding function in CDXSoundEmitter, I just want to setup function pointers. Otherwise my functions in CD3DApp will just look like this:
Code:
void CD3DApp::PlaySound(DWORD dwID)
{
//SoundFX is a valid CDXSoundEmitter object
SoundFX.PlaySound(dwID);
}
A lot of calling for no reason. I want to attach the function pointer in CD3DApp to the function in CDXSoundEmitter.
But my problem is that the declaration inside of CD3DApp is preceded with __thiscall instead of (__cdecl *). And I cannot declare a function pointer with call type (__cdecl).
Sorry if this confuses you, but I know of no other way to explain it.
I'm not trying to override C++ protection mechanisms with this, I'm trying to use one function call to call into CDXSoundEmitter from CD3DApp instead of two.
This is an example of the error I'm getting - obviously lvalue does not equal rvalue, but how do I fix?
D:\VC6Projects\Zelda\CD3DApp.cpp(26) : error C2440: '=' : cannot convert from 'unsigned int (__thiscall CDXSoundEmitter::*)(unsigned short *)' to 'unsigned int (__cdecl *)(unsigned short *)'
There is no context in which this conversion is possible
I know this is possible because in Windows you can register your WndProc with Windows and the WndProc can be a member of a class. So Windows calls the WndProc in the class instead of one sitting in the global namespace.
This will also allow me to control all access to CDXSoundEmitter and only allow access to the functions necessary for the game. All other creation functions will not be accessible and you will never ever have access to the core DirectMusicSoundSegment8, DirectMusicPerformance8, or DirectMusicLoader8 objects.
Exactly what I want. This means that by not returning a reference to the interface pointer, you cannot mistakenly call release and/or AddRef() on the object. I don't want to grant access to the actual object. Besides it makes sense that since the sound engine is part of the bigger engine that you should have to go through CD3DApp to play sounds.
CD3DApp.h
Code:
#ifndef CD3DApplication
#define CD3DApplication
#include <d3dx9.h>
#include <string>
#include <limits>
#include "CDXInput.h"
#include "CMouse.h"
#include "CKeyboard.h"
#include "CDXAudio.h"
const float INFINITY = FLT_MAX;
const float EPSILON = 0.001f;
LRESULT CALLBACK g_WndProc(HWND hwnd,UINT msg,WPARAM wParam,LPARAM lParam);
#define CDX_AUDIO_SOUNDFX 0x01
#define CDX_AUDIO_MUSIC 0x03
class CD3DApp
{
protected:
//...
//<snip>
//...
CDXAudio Audio;
CDXSoundEmitter *SoundFX;
CDXSoundEmitter Music;
public:
int EnterMsgLoop(bool (*DisplayFunc)(float timeDelta));
//
//<snip>
//
//Sound function pointers
unsigned int (CDXSoundEmitter::*LoadSound)(WCHAR *Filename);
};
#endif
CD3DApp.cpp
Code:
//...
//<snip>
//....
bool CD3DApp::InitAudio(DWORD dwNumPChannels,DWORD dwMSLatency)
{
Audio.Create(dwNumPChannels);
Audio.SetLatency(dwMSLatency);
SoundFX=new CDXSoundEmitter();
SoundFX->Create(Audio.GetLoader(),Audio.GetPerformance());
//Music.Create(Audio.GetLoader(),Audio.GetPerformance());
LoadSound=SoundFX->LoadSound;
//Play=SoundFX.Play;
//PlayWithCheck=&SoundFX.PlayWithCheck;
//GetPlaying=&SoundFX.GetPlaying;
//SetLooping=&SoundFX.SetLooping;
//SetVolume=NULL;
//Stop=&SoundFX.Stop;
return true;
}
//...
//<snip>
//...
Amd some of you might say I should just return a copy of the interface pointer back to the user, but that entails a lot of COM problems just waiting to happen. That means that the user MUST call Release() on their copy of the interface or you have a serious problem.