Strange SIGSEGV fault

Started by
16 comments, last by adder_noir 12 years, 9 months ago
Yeah sure I'll post it up later today. Thanks, I thought it was weird too.
Advertisement
Ok here goes.

This is the method that does not work.

// application .cpp
LPD3DXEFFECT effect = NULL; // global variable

// a typecast and an initialisation ready to be assigned to the function pointer in the DLL
typedef void (*CREATEEFFECTFROMFILE) (LPDIRECT3DDEVICE9,
LPCTSTR,
LPD3DXEFFECT,
LPD3DXBUFFER,
D3DXHANDLE*);

CREATEEFFECTFROMFILE _CreateEffectFromFile = NULL;

...


// the function that loads the dll and get's the dll's function pointer (prototype not shown above)
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;
}


In the DLL:

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;
}


This is the method that does work.


// application .cpp
LPD3DXEFFECT effect = NULL; // global variable

// a typecast and an initialisation ready to be assigned to the function pointer in the DLL
typedef LPD3DXEFFECT (*CREATEEFFECTFROMFILE) (LPDIRECT3DDEVICE9,
LPCTSTR,
LPD3DXEFFECT,
LPD3DXBUFFER,
D3DXHANDLE*);

CREATEEFFECTFROMFILE _CreateEffectFromFile = NULL;

...


// the function that loads the dll and get's the dll's function pointer (prototype not shown above)
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");
effect = _CreateEffectFromFile(d3ddev,
"specular.fx",
effect,
errorLog,
&technique);
}

return;
}


In the DLL:

LPD3DXEFFECT CreateEffectFromFile(LPDIRECT3DDEVICE9 d3ddev,
LPCTSTR shaderFile,
LPD3DXEFFECT effect, // this argument is irrelevant 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;
}


That's how it all is at the moment. Very strange. I'll pm you to make sure you see this. Thanks.
Can you post the complete compiler and linker settings for both the EXE and DLL projects? Sounds to me like there's some discrepancy that's causing this, because the first code you posted definitely looks like it should work fine.

Wielder of the Sacred Wands
[Work - ArenaNet] [Epoch Language] [Scribblings]

Yeah sure, thanks for the reply. I'll post it all up tomorrow cheers :)

LPD3DXEFFECT CreateEffectFromFile(LPDIRECT3DDEVICE9 d3ddev,
LPCTSTR shaderFile, <<---- This here
LPD3DXEFFECT effect,
LPD3DXBUFFER errorLog,
D3DXHANDLE* technique)


Don't put types that can and do change based upon compiler flags in dll interfaces.

It's entirely likely that the dll of the non-working version is compiled with UNICODE defined which would make that parameter a "LPCWSTR shaderFile" while the app (which doesn't have UNICODE defined) sees it as "LPCSTR shaderFile". If this is the case then the string being passed to D3DXCreateEffectFromFile is borked and your lack of error checking lets the function blow up dereferencing a NULL/garbage tempEffect variable.

This is probably what ApochPiq was getting at but it's something you need to be aware of even if this isn't your immediate problem.
Thanks for the reply. I have already tried the unicode strings and also with full error checking and the specific UNICODE function call D3DXCreateEffectFromFileW to no avail. It's been stripped out here for convenience.

I'll attempt it one more time to make sure.

Surely though if the string was the problem niether version would function. I have built both the application and the DLL myself in the same compiler with the same settings.

Bizarre!
I can't find where the exact compiler settings are. I am using the Code::Blocks default layout. I might head over and post this on the Code::Blocks forum and see what they say. If they produce anything useful I'll come back. It isn't such a big deal anyway because to keep the concept of encapsulation when I build this into the real engine I'm using there will be no API specific variables on the application side anyway so it should be fine, provided I make sure both are nullified in the classes that create them when their Release() member function is called :rolleyes:

Thanks everyone for the help :)
Hi this problem has now been solved.

It was being caused by the argument list to the DLL function.

Because I was passing a pointer into the function, not a pointer-to-a-pointer, the function was making a copy of the effect pointer which got deleted when it went out of scope in the DLL function.

A real schoolboy error (apparently) :rolleyes:

Here is a working version (although perhaps still not perfect but it shows the fix anyhow):
void CreateEffectFromFile(LPDIRECT3DDEVICE9 d3ddev,
LPCTSTR shaderFile,
LPD3DXEFFECT* ppEffect,
LPD3DXBUFFER errorLog,
D3DXHANDLE* technique)
{
HRESULT hr = D3DXCreateEffectFromFile(d3ddev, shaderFile, 0, 0, 0, 0, ppEffect, &errorLog);

(*ppEffect)->FindNextValidTechnique(NULL, technique);

return;
}


And that's it. I thought that the function would preserve the pointer but it didn't it copied it. A pointer to a pointer fixed it :cool: :D

This topic is closed to new replies.

Advertisement