I tried getting an answer for this on GameDev. Some good very helpful replies but generally speaking no adequate solution.
I also made the mistake of asking on the IDE's forum. Last time I try that one. I value my sanity too much to ask anything again on there.
So in the hope someone can actually answer my question without swooping in with the lock button like the world's biggest drama queen I thought I'd ask on here.
I've had a few distanced and cold replies on here before but I've had many many helpful and detailed ones too (which is my own preferred brand of advice).
So here goes:
I've made an application and a DLL. The application loads the DLL and calls an API specific function within the DLL. Have a look:
The function defined inside the DLL.
Code:
void CreateEffectFromFile(LPDIRECT3DDEVICE9 d3ddev,
LPCTSTR shaderFile,
LPD3DXEFFECT effect,
LPD3DXBUFFER errorLog,
D3DXHANDLE* technique)
{
HRESULT hr = D3DXCreateEffectFromFile(d3ddev, shaderFile, 0, 0, 0, 0, &effect, &errorLog);
effect->FindNextValidTechnique(NULL, technique);
return;
}
The application code that calls this:
Code:
LPD3DXEFFECT effect // global pointer within the application
HMODULE m_hDLL // the DLL handler
typedef void (*CREATEEFFECTFROMFILE) (LPDIRECT3DDEVICE9,
LPCTSTR,
LPD3DXEFFECT,
LPD3DXBUFFER,
D3DXHANDLE*);
CREATEEFFECTFROMFILE _CreateEffectFromFile = NULL;
... sometime later ...
void CreateEffectFromFileDLL(void)
{
m_hDLL = NULL;
m_hDLL = LoadLibrary("MyDLL.dll");
if(!m_hDLL)
{
MessageBox(NULL,
"Loading MyDLL.dll from lib failed.",
"DLL Loading - error", MB_OK | MB_ICONERROR);
return;
}
if (m_hDLL)
{
_CreateEffectFromFile = (CREATEEFFECTFROMFILE) GetProcAddress(m_hDLL, "CreateEffectFromFile");
_CreateEffectFromFile(d3ddev,
"specular.fx",
effect,
errorLog,
&technique);
}
return;
}
All looks ok. But it does not work and here's the strange part. If the code is changed as follows:
Code:
LPD3DXEFFECT CreateEffectFromFile(LPDIRECT3DDEVICE9 d3ddev,
LPCTSTR shaderFile,
LPD3DXEFFECT effect, // unused in this method
LPD3DXBUFFER errorLog,
D3DXHANDLE* technique)
{
LPD3DXEFFECT tempEffect;
HRESULT hr = D3DXCreateEffectFromFile(d3ddev, shaderFile, 0, 0, 0, 0, &tempEffect, &errorLog);
tempEffect->FindNextValidTechnique(NULL, technique);
return tempEffect;
}
... and in the application
Code:
LPD3DXEFFECT effect // global pointer within the application
HMODULE m_hDLL // the DLL handler
typedef LPD3DXEFFECT (*CREATEEFFECTFROMFILE) (LPDIRECT3DDEVICE9,
LPCTSTR,
LPD3DXEFFECT,
LPD3DXBUFFER,
D3DXHANDLE*);
CREATEEFFECTFROMFILE _CreateEffectFromFile = NULL;
... sometime later ...
void CreateEffectFromFileDLL(void)
{
m_hDLL = NULL;
m_hDLL = LoadLibrary("MyDLL.dll");
if(!m_hDLL)
{
MessageBox(NULL,
"Loading MyDLL.dll from lib failed.",
"DLL Loading - error", MB_OK | MB_ICONERROR);
return;
}
if (m_hDLL)
{
effect = _CreateEffectFromFile = (CREATEEFFECTFROMFILE) GetProcAddress(m_hDLL, "CreateEffectFromFile");
_CreateEffectFromFile(d3ddev,
"specular.fx",
effect,
errorLog,
&technique);
}
return;
}
This works. Why I have no idea.
Simply put if I just make a pointer in the application, pass it into the DLL then the pointer is seen as valid in the DLL but NULL in the application.
But if I make the function in the DLL return a temporary variable (or perhaps even the very pointer passed into it!) it is valid in the application and the methods of the class it points to can be called.
Weird. It isn't a big problem because to keep encapsulation and API independency of the engine I'm working on all API specific stuff needs to be inside the DLL anyway, so there will never be a need to pass a pointer across an application into a DLL and hope it survives in this fashion.
It would be nice to know why this happens though.
Any ideas? thanks