Hello,
I've just started using Boost.DLL in order to simplify loading of various WinApi functions exclusive to specific Windows versions, however, I've faced the issue (or may be it's just misunderstanding from my side).
it's pretty well-known there are multiple calling conventions around - cdecl, stdcall, fastcall, etc. most of WinApi functions are in stdcall calling convention, while default one for MSVC 2015 is cdecl (unless compiler options are changed).
I've read documentation onĀ http://apolukhin.github.io/Boost.DLL/, as well as I've scanned source code a bit, but didn't find any avidence on how to specify calling convention of function I am importing.
example from tutorial9 works just fine, as it uses timeGetTime function which has no arguments. however, if I modify example (see my code below copy-pasted from tutorial9) to import function with at least one argument or more (e.g. GetStdHandle) I receive the following debugger error:
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.
this indicates that Boost.DLL incorrectly interpreted stdcall function as cdeacl function that caused stack corruption.
I've googled a bit about calling convention and boost, and found the following two definitions:
#define BOOST_BIND_ENABLE_STDCALL
#define BOOST_MEM_FN_ENABLE_STDCALL
unfortunately adding them has no effect.
if I add explicit __stdcall into the function typedef, then program no longer compiles
#include <boost/dll/import.hpp> // for import #include <iostream> #include <windows.h> namespace dll = boost::dll; int main() { typedef HANDLE(GetStdHandle_fn)(DWORD nStdHandle); // function signature boost::function<GetStdHandle_fn> plugin = dll::import<GetStdHandle_fn>( // we import using C name, not alias! Using `import<>` "Kernel32.dll", // Windows dll "GetStdHandle" // function name ); std::cout << "timeGetTime() returned " << plugin(STD_OUTPUT_HANDLE) << std::endl; return 0; }