[英]Specify function return type as template parameter in c++
我试图给我的 function 一个模板参数的返回类型(以改进类型检查),这是一个 function 参考。 这是我到目前为止所尝试的:
#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); }
但是,我收到以下关于proxyFunction
的编译时错误:
没有 function 模板的实例与参数列表参数类型匹配:(const char [32], const char [20])
我不太确定如何处理这个错误,因为它相当模糊。 所以我想知道是否有人可以解释我的片段中的问题是什么?
PS 我正在使用带有 C++ 17 标准的 MS VS 2019,以防万一。
您的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;
}
更新:根据@MooingDuck 的评论,看起来您实际上是在尝试将您的代理 function 传递给模板,并让它推断出必要的参数和返回类型以用于 DLL ZC1C4245268E687A94D1 如果是这样,请尝试更多类似的方法:
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;
}
所以事实证明std::function
实现了我正在寻找的那种行为。
例如,如果我的虚拟 DLL function 定义如下:
#include <Windows.h> #define DllExport extern "C" __declspec( dllexport ) DllExport int SQUARE(int number){ return number * number; } BOOL APIENTRY DllMain(HMODULE hModule, DWORD ul_reason_for_call, LPVOID lpReserved){ return TRUE; }
然后我会按如下方式导入它:
#include <Windows.h> #include <iostream> #include <functional> HMODULE dummyHandle = nullptr; template<typename signature> std::function<signature> proxyFunction(HMODULE hModule, LPCSTR functionName){ auto funcPtr = GetProcAddress(hModule, functionName); std::cout << (funcPtr ? "Proxy success" : "Proxy fail") << std::endl; return std::function<signature>(reinterpret_cast<signature*>(funcPtr)); } int SQUARE(int number){ auto proxy = proxyFunction<decltype(SQUARE)>(dummyHandle, __FUNCTION__); return proxy ? proxy(number) : -1; } int main(){ dummyHandle = LoadLibraryA("C:\\Absolute\\Path\\To\\Dummy.dll"); if(dummyHandle) std::cout << "Square of 7 is " << SQUARE(7) << std::endl; else std::cout << "Failed to load dummy dll. Last Error: " << GetLastError() <<std::endl; system("pause"); }
我喜欢这种方法,因为它无需定义辅助构造即可启用基本的 static 类型检查。 但是,我仍然认为还有改进的余地。 每次调用proxyFunction
时,我们都必须将 function 包装到decltype(...)
中。 有谁知道如何以简单的方式在proxyFunction
中隐藏该位?
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.