C++ 运行时检查失败-不同的调用约定

C++ 运行时检查失败-不同的调用约定,c++,winapi,C++,Winapi,我想加载一个示例库(即user32),然后使用该库的一个导出函数(如messageboxw)向用户显示一条消息。我的程序运行正常,它会显示消息,但当我单击按钮关闭程序时,它会显示以下消息: 运行时检查失败#0-ESP的值未正确保存 跨越函数调用。这通常是调用 用一个调用约定和一个函数指针声明的函数 使用不同的调用约定声明 我的源代码: #include <Windows.h> #include <iostream> #include <functional>

我想加载一个示例库(即user32),然后使用该库的一个导出函数(如messageboxw)向用户显示一条消息。我的程序运行正常,它会显示消息,但当我单击按钮关闭程序时,它会显示以下消息:

运行时检查失败#0-ESP的值未正确保存 跨越函数调用。这通常是调用 用一个调用约定和一个函数指针声明的函数 使用不同的调用约定声明

我的源代码:

#include <Windows.h>
#include <iostream>
#include <functional>

typedef int(*MsgBOX)
(
    HWND    hWnd,
    LPCWSTR lpText,
    LPCWSTR lpCaption,
    UINT    uType
);

int main(int argc, char* argv[])
{
    HINSTANCE handle_user32_dll = LoadLibrary(TEXT("User32.dll"));
    std::function<int(HWND, LPCWSTR, LPCWSTR, UINT)> MsgBoxInstance;
    
    if(!handle_user32_dll)
    {
        std::cout << "Dll isn't loaded successfuly." << std::endl;
    }
    else
    {
        MsgBoxInstance = reinterpret_cast<MsgBOX>(GetProcAddress(handle_user32_dll, "MessageBoxW"));
        if (!MsgBoxInstance)
        {
            std::cout << "Function didn't resolved.";
        }
        else
        {
            MsgBoxInstance(NULL, L"Resource not available\nDo you want to try again?", L"Account Details", MB_ICONWARNING | MB_CANCELTRYCONTINUE | MB_DEFBUTTON2);
        }
    }

    FreeLibrary(handle_user32_dll);

    return 0;
}
#include <Windows.h>
#include <iostream>
#include <functional>

typedef WINUSERAPI int(WINAPI *MsgBOX)
(
    _In_opt_ HWND hWnd,
    _In_opt_ LPCWSTR lpText,
    _In_opt_ LPCWSTR lpCaption,
    _In_ UINT uType
);

int main(int argc, char* argv[])
{
    HINSTANCE handle_user32_dll = LoadLibrary(TEXT("User32.dll"));
    std::function<int(HWND, LPCWSTR, LPCWSTR, UINT)> MsgBoxInstance;

    if(!handle_user32_dll)
    {
        std::cout << "Dll isn't loaded successfuly." << std::endl;
    }
    else
    {
        MsgBoxInstance = reinterpret_cast<MsgBOX>(GetProcAddress(handle_user32_dll, "MessageBoxW"));

        if (!MsgBoxInstance)
        {
            std::cout << "Function didn't resolved.";
        }
        else
        {
            MsgBoxInstance(NULL, TEXT("Resource not available\nDo you want to try again?"), TEXT("Account Details"), MB_ICONWARNING | MB_CANCELTRYCONTINUE | MB_DEFBUTTON2);
        }
    }

    FreeLibrary(handle_user32_dll);

    return 0;
}
#包括
#包括
#包括
typedef int(*MsgBOX)
(
HWND HWND,
LPCWSTR lpText,
LPCWSTR lpCaption,
UINT uType
);
int main(int argc,char*argv[])
{
HINSTANCE handle_user32_dll=LoadLibrary(文本(“user32.dll”);
函数msgboxistance;
如果(!handle\u user32\u dll)
{

根据注释,我解决了更改typedef签名的问题

更正的源代码:

#include <Windows.h>
#include <iostream>
#include <functional>

typedef int(*MsgBOX)
(
    HWND    hWnd,
    LPCWSTR lpText,
    LPCWSTR lpCaption,
    UINT    uType
);

int main(int argc, char* argv[])
{
    HINSTANCE handle_user32_dll = LoadLibrary(TEXT("User32.dll"));
    std::function<int(HWND, LPCWSTR, LPCWSTR, UINT)> MsgBoxInstance;
    
    if(!handle_user32_dll)
    {
        std::cout << "Dll isn't loaded successfuly." << std::endl;
    }
    else
    {
        MsgBoxInstance = reinterpret_cast<MsgBOX>(GetProcAddress(handle_user32_dll, "MessageBoxW"));
        if (!MsgBoxInstance)
        {
            std::cout << "Function didn't resolved.";
        }
        else
        {
            MsgBoxInstance(NULL, L"Resource not available\nDo you want to try again?", L"Account Details", MB_ICONWARNING | MB_CANCELTRYCONTINUE | MB_DEFBUTTON2);
        }
    }

    FreeLibrary(handle_user32_dll);

    return 0;
}
#include <Windows.h>
#include <iostream>
#include <functional>

typedef WINUSERAPI int(WINAPI *MsgBOX)
(
    _In_opt_ HWND hWnd,
    _In_opt_ LPCWSTR lpText,
    _In_opt_ LPCWSTR lpCaption,
    _In_ UINT uType
);

int main(int argc, char* argv[])
{
    HINSTANCE handle_user32_dll = LoadLibrary(TEXT("User32.dll"));
    std::function<int(HWND, LPCWSTR, LPCWSTR, UINT)> MsgBoxInstance;

    if(!handle_user32_dll)
    {
        std::cout << "Dll isn't loaded successfuly." << std::endl;
    }
    else
    {
        MsgBoxInstance = reinterpret_cast<MsgBOX>(GetProcAddress(handle_user32_dll, "MessageBoxW"));

        if (!MsgBoxInstance)
        {
            std::cout << "Function didn't resolved.";
        }
        else
        {
            MsgBoxInstance(NULL, TEXT("Resource not available\nDo you want to try again?"), TEXT("Account Details"), MB_ICONWARNING | MB_CANCELTRYCONTINUE | MB_DEFBUTTON2);
        }
    }

    FreeLibrary(handle_user32_dll);

    return 0;
}
#包括
#包括
#包括
typedef WINUSERAPI int(WINAPI*MsgBOX)
(
_在_opt_hwndhwnd中,
_在_opt_ucwstrlptext中,
_在_opt_LPCWSTR lpCaption中,
_输入输出类型
);
int main(int argc,char*argv[])
{
HINSTANCE handle_user32_dll=LoadLibrary(文本(“user32.dll”);
函数msgboxistance;
如果(!handle\u user32\u dll)
{

std::难道你不只是链接到user32,然后从windows标题中使用
MessageBoxW
是有原因的吗?如果这确实是你想要的路径,那么你需要确保你的typedef与标题中的函数声明完全匹配,包括你想要调用DLL函数的调用约定,你需要知道。如果您是从教程中获得这段代码的,那么它应该以粗体、响亮的术语提及这些调用约定因此,动态加载
user32
是不寻常的,而且很少有正当理由。它只是一个宏,表示
\uu stdcall
@pau调用约定对每个函数调用都很重要。这与DLL无关。您可以而且应该摆脱
WINUSERAPI
,在这种情况下不需要它。