Jump to content
  • Advertisement

Archived

This topic is now archived and is closed to further replies.

langguy

Stupid DLL issue...

This topic is 5536 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

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?

Share this post


Link to post
Share on other sites
Advertisement
Guest Anonymous Poster
i think if you recompile the dll in vs.net it fixes it.

Share this post


Link to post
Share on other sites
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.

Share this post


Link to post
Share on other sites
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

Share this post


Link to post
Share on other sites
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 *);

Share this post


Link to post
Share on other sites
__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



Share this post


Link to post
Share on other sites

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!