C++ 错误:从 'long long int (*)()' 到 'long long int (*)(int)' 的转换无效

问题描述 投票:0回答:1

我正在尝试将 WinAPI 函数的调用包装在将自动检查错误的函数中:

template<typename T = void,typename function, typename ...Args>
T winapi_wrapper(function caller, Args&&... args)
{
    static_assert(not std::is_function_v<function>);
    auto check_error = [](){ GetLastError() != 0 ? throw std::runtime_error{"error in a WinAPI call"}  : [](){}();};
    if constexpr(!std::is_void_v<T>)
    {
       T result = caller(std::forward<Args>(args)...);
       check_error();
       return result;
    }
    else
    {
       caller(std::forward<Args>(args)...);
       check_error();
    }
}
int main()
{
   using func_zero_args = long long (__cdecl*)();
   using func_one_arg = long long (__cdecl*)(int);
   std::unique_ptr<HINSTANCE__, decltype(&FreeLibrary)> dll_handler{winapi_wrapper<HINSTANCE>(&LoadLibraryA,"C:/test.dll"), FreeLibrary};
   func_zero_args no_arg_ptr = winapi_wrapper<func_zero_args>(&GetProcAddress, dll_handler.get(), "func_no_args");
   func_one_arg one_arg_ptr = winapi_wrapper<func_one_arg>(&GetProcAddress, dll_handler.get(), "one_arg_fn");
}

第一个调用按预期工作,但第二个调用未编译,并出现以下错误:

Cannot initialize a variable of type 'long long (*)(int)' with an rvalue of type 'long long (*)()': different number of parameters (1 vs 0)

我试图改变

func_one_arg

的类型
int main()
{
   using func_zero_args = long long (__cdecl*)();
   using func_one_arg = void (__cdecl*)();
   std::unique_ptr<HINSTANCE__, decltype(&FreeLibrary)> dll_handler{winapi_wrapper<HINSTANCE>(&LoadLibraryA,"C:/test.dll"), FreeLibrary};
   func_zero_args no_arg_ptr = winapi_wrapper<func_zero_args>(&GetProcAddress, dll_handler.get(), "func_no_args");
   func_one_arg one_arg_ptr = winapi_wrapper<func_one_arg>(&GetProcAddress, dll_handler.get(), "one_arg_fn");
}

所以现在的错误是:

Cannot initialize a variable of type 'void (*)()' with an rvalue of type 'long long (*)()': different return type ('void' vs 'long long')

c++ variadic-templates template-meta-programming
1个回答
0
投票

问题在于,

GetProcAddress
返回一个指向long long的指针,当我编写这个包装器时我错过了这一点,所以解决方案是将结果转换为类型
T

template<typename T = void,typename function, typename ...Args>
T winapi_wrapper(function caller, Args&&... args)
{
    static_assert(not std::is_function_v<function>);
    auto check_error = [](){ GetLastError() != 0 ? throw std::runtime_error{"error in a WinAPI call"}  : [](){}();};
    if constexpr(!std::is_void_v<T>)
    {
       T result = (T)caller(std::forward<Args>(args)...);
       check_error();
       return result;
    }
    else
    {
       caller(std::forward<Args>(args)...);
       check_error();
    }
}
© www.soinside.com 2019 - 2024. All rights reserved.