Well, i am having some issues with an error that i don’t understand.
These are the two related files:
Inside DLLExporter:
#ifdef LOGGER_EXPORTS
#define LOGGER_API __declspec(dllexport) __stdcall
#else
#define LOGGER_API __declspec(dllimport) __stdcall
#endif
typedef long (CALLBACK *LPFNTIMER)( void );
// Exported Functions
bool LOGGER_API Initialize( std::string filename, bool ShowConsole = true );
bool LOGGER_API Release( void );
bool LOGGER_API SetTimer( LPFNTIMER );
bool LOGGER_API Initialize(std::string filename, bool ShowConsole)
{
[...]
}
bool LOGGER_API Release()
{
[...]
}
bool LOGGER_API SetTimer(LPFNTIMER fn)
{
[...]
}
inside DLLExporter.def
LIBRARY DLLExporter.dll
EXPORTS
Initialize
Release
SetTimer
inside DLLImporter:
typedef long (__stdcall *LPFNTIMER)( void );
typedef bool (__stdcall *LPFNINITIALIZER)( string, bool );
typedef bool (__stdcall *LPFNTIMERSETUP)( LPFNTIMER );
typedef bool (__stdcall *LPFNRELEASER)( void );
[...]
long __stdcall TimerFunc()
{
return 0;
}
[...]
if (g_DLLExporter == NULL)
return false;
LogInit = (LPFNINITIALIZER)GetProcAddress(g_DLLExporter, "Initialize");
LogRelease = (LPFNRELEASER)GetProcAddress(g_DLLExporter, "Release");
LogTimer = (LPFNTIMERSETUP)GetProcAddress(g_DLLExporter, "SetTimer");
if ( LogInit == NULL || LogRelease == NULL || LogTimer == NULL)
return false;
if (!LogInit("test.log", true))
return false;
if (!LogRelease())
return false;
if (!LogTimer(TimerFunc))
return false;
This code runs all the way through to the LogTimer call which fails, with the Run-Time Check Failure #0 message.
Run-Time Check Failure #0 – The value
of ESP was not properly saved across a
function call. This is usually a
result of calling a function declared
with one calling convention with a
function pointer declared with a
different calling convention.
I have already noted the __stdcall issues reported elsewhere, but as you can see above i have that included, and i even forced the __stdcall calling convention in the project properties (MSVS 2010). Any thoughts as to why i would get the error only on the timer function and not on the init or release functions?
Just thinking, perhaps if you call LogTimer() before LogRelease()?
And what about passing the proper parameters to Initialize and SetTimer?