[英]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.