当前位置: 首页 > 知识库问答 >
问题:

在C++中指定函数返回类型为模板参数

宋俊艾
2023-03-14
#include <Windows.h>

template <typename func>
decltype(auto) proxyFunction(LPCSTR dllPath, LPCSTR functionName){
    auto funcType = decltype(func);

    funcType funcPtr = (funcType) GetProcAddress(LoadLibraryA(dllPath), functionName);

    if(funcPtr)
        std::cout << "Proxy success" << std::endl;
    else
        std::cout << "Proxy fail" << std::endl;
    
    return funcPtr;
}

BOOL GetFileVersionInfoProxy(LPCSTR lptstrFilename, DWORD dwHandle, DWORD dwLen, LPVOID lpData){
    auto getFileVersion = proxyFunction<GetFileVersionInfoProxy>("C:\\Windows\\System32\\Version.dll", "GetFileVersionInfoA");
    getFileVersion(lptstrFilename, dwHandle, dwLen, lpData);
}

共有1个答案

鲍国兴
2023-03-14

您的func模板参数已经是您要返回的类型,所以只需按原样使用它,不需要使用decltype(auto)。您使用auto funcType=decltype(func);是完全错误的。

请尝试以下操作:

template <typename funcType>
funcType proxyFunction(LPCSTR dllPath, LPCSTR functionName)
{
    funcType funcPtr = (funcType) GetProcAddress(LoadLibraryA(dllPath), functionName);

    if (funcPtr)
        std::cout << "Proxy success" << std::endl;
    else
        std::cout << "Proxy fail" << std::endl;
    
    return funcPtr;
}

BOOL GetFileVersionInfoProxy(LPCSTR lptstrFilename, DWORD dwHandle, DWORD dwLen, LPVOID lpData)
{
    using GetFileVersionInfoA_FuncType = BOOL (WINAPI *)(LPCSTR, DWORD, DWORD, LPVOID);

    auto getFileVersion = proxyFunction<GetFileVersionInfoA_FuncType>("C:\\Windows\\System32\\Version.dll", "GetFileVersionInfoA");
    if (getFileVersion)
        return getFileVersion(lptstrFilename, dwHandle, dwLen, lpData);

    return FALSE;
}

或者,如果让编译器为您推导模板参数,则可以省略传递模板参数:

template <typename funcType>
bool proxyFunction(LPCSTR dllPath, LPCSTR functionName, funcType &funcPtr)
{
    funcPtr = (funcType) GetProcAddress(LoadLibraryA(dllPath), functionName);

    if (funcPtr)
        std::cout << "Proxy success" << std::endl;
    else
        std::cout << "Proxy fail" << std::endl;
    
    return (funcPtr != nullptr);
}

BOOL GetFileVersionInfoProxy(LPCSTR lptstrFilename, DWORD dwHandle, DWORD dwLen, LPVOID lpData)
{
    using GetFileVersionInfoA_FuncType = BOOL (WINAPI *)(LPCSTR, DWORD, DWORD, LPVOID);

    GetFileVersionInfoA_FuncType getFileVersion;
    if (proxyFunction("C:\\Windows\\System32\\Version.dll", "GetFileVersionInfoA", getFileVersion))
        return getFileVersion(lptstrFilename, dwHandle, dwLen, lpData);

    return FALSE;
}
template <typename RetType, typename... ArgTypes>
struct proxyTraits
{
    using funcType = RetType (WINAPI *)(ArgTypes...);
};

template <typename RetType, typename... ArgTypes>
auto proxyFunction(
    LPCSTR dllPath,
    LPCSTR functionName,
    RetType (*proxy)(ArgTypes...))
{
    using funcType = typename proxyTraits<RetType, ArgTypes...>::funcType;
    funcType funcPtr = (funcType) GetProcAddress(LoadLibraryA(dllPath), functionName);

    if (funcPtr)
        std::cout << "Proxy success" << std::endl;
    else
        std::cout << "Proxy fail" << std::endl;
    
    return funcPtr;
}

BOOL GetFileVersionInfoProxy(LPCSTR lptstrFilename, DWORD dwHandle, DWORD dwLen, LPVOID lpData)
{
    auto getFileVersion = proxyFunction("C:\\Windows\\System32\\Version.dll", "GetFileVersionInfoA", &GetFileVersionInfoProxy);
    if (getFileVersion)
        return getFileVersion(lptstrFilename, dwHandle, dwLen, lpData);

    return FALSE;
}
 类似资料:
  • 我想通过另一个模板参数来指定模板化函数的返回类型。所有这些都在一个类中。 在头文件中:

  • 我使用React和Redux,并将动作类型指定为接口,这样我的还原程序就可以利用标记的联合类型来提高类型安全性。 我有如下类型声明: 我想创建创建这些动作的助手函数,我倾向于使用箭头函数。如果我这样写: 编译器无法提供任何帮助来确保这是一个有效的,因为没有明确指定返回类型。我可以通过执行以下操作显式指定返回类型: 但这需要指定我的函数参数两次,因此冗长且难以阅读。 在使用箭头符号时,有没有一种方法

  • 我遇到了以下代码,其行为是由所有GCC、Clang和MSVC商定的: 现场演示:https://godbolt.org/z/hK6xhesKM 在全局命名空间中声明,并带有推断的返回类型<代码>S 我所期望的是,当用〈code〉U=double〈code〉实例化〈code〉S〈code〉时,它对〈code〉foo()〈code〉的定义被放入全局命名空间,并且〈code〉U〈code〉被替换,因为友

  • 我的函数使用一组给定的输入参数(变量)调用Python函数,并返回包含函数输出的元组(变量,因为输出随调用的函数而变化)。 我正在使用C 11通过MinGW-w64编译器的g端口在视窗10机器上编译。我声明了这个模板变量函数(并调用它)如下: 但是,会引发此错误(为了可读性,缩短为):

  • 我有以下代码: 这段代码会导致编译错误。使用< code>g -std=c 1z编译时,错误显示如下: 使用< code>clang -std=c 1z时,错误为: 我在MSYS2 MinGW-w64环境中运行这些。我的GCC版本是GCC 7.1.0,我的Clang版本是4.0.0;我在GCC和Clang中使用的标准库是与我的GCC编译器捆绑在一起的libstdc。 在我看来,对函数templat

  • 在C++11之前,类模板和函数模板只能含有固定数量的模板参数。C++11增强了模板功能,允许模板定义中包含0到任意个模板参数,这就是可变参数模板。可变参数模板的加入使得C++11的功能变得更加强大,而由此也带来了许多神奇的用法。 可变参数模板 可变参数模板和普通模板的语义是一样的,只是写法上稍有区别,声明可变参数模板时需要在typename或class后面带上省略号...: template<ty