Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Specify function return type as template parameter in c++

I'm trying to give my function a return type of its template parameter(to improve type checking), which is a function reference. Here is what I have attempted so far:

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

However, I am getting the following compile-time error with regards to proxyFunction:

no instance of function template matches the argument list argument types are: (const char [32], const char [20])

I am not quite sure what to make of this error since it is rather vague. So I was wondering if anyone can explain what's the issue in my snippet?

P.S. I am using MS VS 2019 with C++ 17 standard, in case it is helpful.

like image 263
arslancharyev31 Avatar asked Aug 28 '26 01:08

arslancharyev31


1 Answers

Your func template parameter is already the type you want to return, so just use it as-is, there is no need to use decltype(auto). And your use of auto funcType = decltype(func); is just plain wrong.

Try this instead:

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

Alternatively, you can omit passing in the template parameter if you let the compiler deduce it for you:

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

UPDATE: based on @MooingDuck's comment, it looks like you are actually trying to pass your proxy function to the template and have it deduce the necessary parameters and return type for use with the DLL function. If so, then try something more like this instead:

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

Live Demo

like image 72
Remy Lebeau Avatar answered Aug 29 '26 14:08

Remy Lebeau



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!