Boost logo

Boost Users :

Subject: [Boost-users] [DLL] unclear how to specify calling convention for dll::import
From: Konstantin Ivlev (tomskside_at_[hidden])
Date: 2015-10-27 12:37:15


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;
}



Boost-users list run by williamkempf at hotmail.com, kalb at libertysoft.com, bjorn.karlsson at readsoft.com, gregod at cs.rpi.edu, wekempf at cox.net