I havent changed the calling convention for the project so the default is now __cdecl. Thus functions in the DLL file must be decorated. But when I use dependency walker to check, this function is not decorated. This is the first problem.
I build a test client to use this library as follow..
This clients loads the library and calls the function properly. But at the end of the function i get following error..
Code:
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.
which tells that there is something wrong about calling convention or function pointer . Is there something I am missing...
That error occurs also if you have a memory overwrite. It doesn't appear only if there is a calling convention problem.
Originally Posted by sachin871
I havent changed the calling convention for the project so the default is now __cdecl.
How is the function really declared when you compile the DLL? We can't be certain what you're showing us is the actual declaration.
Also, regardless of what you set the default calling convention to, it is easily overriden by using various modifiers on the function declaration (i.e. __stdcall or any of the other macros that have __stdcall in the definition).
Another thing, your DLL is passing strings by value. The only programs that can use your DLL and guarantee that there are no issues are programs compiled for Visual C++ 2005 and for that particular version/service pack of VC 2005. If you want to use the DLL for Visual Studio 2008, you will have to create another DLL for Visual Studio 2008.
The reason is that std::string is a class that may change how things are done internally, depending on version of the compiler. The only function parameter types that are guaranteed to work for all versions of the compiler are integral types (LONG, char, etc.), and pointers to these types, and user-defined POD structs.
To add to this, you must make sure your application is using the DLL version of the runtime. The reason why is again, std::string. You must make sure that the memory manager used for your app is the same one used by the DLL.
There are a lot of problems when passing std::string that go far beyond getting the calling convention correct. What is usually done is that the DLL takes a char buffer, and either fills it in with the information, or reads from it.
You should have a single header file that declares the exported functions. Do you have this? The header is to be used both for the DLL and for any application that calls the function.
Second, the easiest thing is to create a 'C' exported interface to the function:
This is an example of how to define your functions for a 'C' exported interface. If you're including this header when building your DLL, you define BUILDING_DLL in your preprocessor. If you're using it in an app that will use your DLL, you don't define BUILDING_DLL.
By making one common header, you don't make a mistake.
I also changed the return type to LONG. The "bool" is a C++ thing, and there is no guarantee that a "bool" on one version of Visual C++ will be exactly the same as a "bool" on another version of VC++. Yes, a "bool" is an integral type, but there is no standard as to the sizeof(bool). You should return 1 if true, and 0 if false, instead of "true" or "false".
The tricks to getting DLL's to behave properly across compilers, apps, etc. is to use the most generic interface that is viable with respect to parameters and return types.
I am loading the library dynamically using LoadLibrary(). Also I am using .def file, so i guess I dont need to use dllexport and dllimport explicitly.
Actually this is a MFC library and will be used by another MFC library. So we dont need to worry about diff compilers.
The actual problem of calling conventions still exist. I have build a sample Dll and sample client so that ppl can help me. I am attaching the zip with the same.
[note : keep the SampleDll.dll in your C: or change the path in the code]
The point is this -- pointers to non-static class members, and pointers to functions are not compatible. The reason for the crash is that you are trying to call functions using a type that is not correct.
The compiler generates code for a non-class member on the app side, and on the DLL side, the function is really a non-static member function. What ends up happening is that the stack is screwed up at the end of the DLL function call, due to problems with this pointers and other things.
* The Best Reasons to Target Windows 8
Learn some of the best reasons why you should seriously consider bringing your Android mobile development expertise to bear on the Windows 8 platform.