Stupid DLL issue...

Started by
6 comments, last by langguy 20 years, 8 months ago
I am using a Borland DLL that loads bitmaps and retrieves pixels and then returns the result to my Visual C++.NET program by using pointers. The actual code works perfectly (it returns valid results, etc.). The problem is, however, whenever I call a function in this DLL, I get this stupid message:
quote: 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.
How can I fix this so that I don''t get this error message at all?
Advertisement
i think if you recompile the dll in vs.net it fixes it.
Well, the reason I compiled the DLL in borland was so that I could use several VCL classes that aren''t available in MSVC++. So, recompiling the DLL in MSVC++ wouldn''t work.
I have had this problem before and I''m pretty sure it''s due to the calling convention used on the function. (as the message says in fact, I just noticed reading back)

The error pertains to the stack pointer being changed which is due to the method used to push/pop the arguments to the function on and off the stack.

We generally use __cdecl or __stdcall as a convention, __cdecl being the default where the caller cleans the stack. If the DLL is using __stdcall where the callee cleans the stack then that''s the problem. So, try using the opposite calling convention to the one you are using and see if it fixes your problem.


"Absorb what is useful, reject what is useless, and add what is specifically your own." - Lee Jun Fan
"Absorb what is useful, reject what is useless, and add what is specifically your own." - Lee Jun Fan
Well, borland will only compile the functions as exports from the DLL if I use __declspec{dllexport). I''ve tried putting __declspec(dllimport), __declspec(dllexport), and __declspec(selectany) in front of my function declarations in my MSVC++ source, but I still get the same error message.
Here is my borland code:
extern "C" __declspec(dllexport) bool LoadBitmapToDll(char* czFileName);extern "C" __declspec(dllexport) bool GetPixelAt(int x, int y, char cValue,                                                unsigned short *usResult);

Here is my MSVC++ code:
typedef __declspec(?????) bool (CALLBACK* LPFNDLLFUNC1)(char *);typedef __declspec(?????) bool (CALLBACK* LPFNDLLFUNC2)(int, int, char, unsigned short *);

__declspec has nothing to do with the calling convention, it just tells the linker if the function should be exported or imported.

borland
bool LoadBitmapToDll(char* czFileName);

msvc
bool (CALLBACK* LPFNDLLFUNC1)(char *);

grep on CALLBACK and you''ll find that it equates to _stdcall - it''s not a type so the location of the pointer should be with the function pointer name.

Change the borland code to
extern "C" __declspec(dllexport) bool _stdcall LoadBitmapToDll(char* czFileName);

If not _stdcall then __stdcall. Also consult the borland docs on .def files - in particular how to use them to remove the leading underscore and @params from the resulting function names - ie the name mangling.

On the msvc side, the __declspec has no bearing on a function pointer typedef. It''s for use on function prototypes.

__declspec(dllimport) bool CALLBACK LPFNDLLFUNC1(char *);

If you want to stick with the function pointer typedef, use it like so

typedef bool (CALLBACK *LPFNDLLFUNC1)(char *);

LPFNDLLFUNC1 lpfnDllFunc1 = NULL;

HMODULE hMod = LoadLibrary("MyDll");

lpfnDllFunc1 = (LPFNDLLFUNC1)GetProcAddress(hMod,"MyExportFunctionName");
if ( NULL == lpfnDllFunc1 ) {
// bad pointer, call GetLastError for details



"I thought what I'd do was, I'd pretend I was one of those deaf-mutes." - the Laughing Man
Thank you so much! Putting __stdcall in front of my borland functions fixed it.
no problem
"I thought what I'd do was, I'd pretend I was one of those deaf-mutes." - the Laughing Man

This topic is closed to new replies.

Advertisement