在下面的代碼的方式,我試圖函數指針存儲在一個載體,但每個函數指針都有不同的簽名。是否有存儲不同的函數指針類型的容器
下面的代碼的想法是,當我加載一個DLL時,我只需使用一個循環來將所有函數從DLL加載到向量中。然後,當我想調用一個函數時,我只是通過名稱或索引來調用它,並傳遞可變數量的參數。但是我真的很想按照我加載它們的方式調用函數:通過循環。
#if defined _WIN32 || defined _WIN64
#include <windows.h>
#else
#include <dlfcn.h>
#endif
#include <iostream>
#include <cstdint>
#include <vector>
#include <functional>
class Library
{
private:
void* Module;
public:
Library(std::string Library);
~Library();
template<typename T>
T AddressOf(std::string FunctionName);
template<typename T>
bool AddressOf(T &FunctionDefinition, std::string FunctionName);
template<typename T, typename ...Args>
auto CallFunction(void* Function, Args... args) -> decltype(reinterpret_cast<T>(Function)(args...));
};
Library::Library(std::string Library)
{
#if defined _WIN32 || defined _WIN64
this->Module = LoadLibrary(Library.c_str());
#else
this->Module = dlopen(Library.c_str(), RTLD_LAZY);
#endif
}
Library::~Library()
{
#if defined _WIN32 || defined _WIN64
FreeLibrary(static_cast<HMODULE>(this->Module));
#else
dlclose(this->Module);
#endif
}
template<typename T>
T Library::AddressOf(std::string FunctionName)
{
#if defined _WIN32 || defined _WIN64
return reinterpret_cast<T>(GetProcAddress(static_cast<HMODULE>(this->Module), FunctionName.c_str()));
#else
return reinterpret_cast<T>(dlsym(this->Module, FunctionName.c_str()));
#endif
}
template<typename T>
bool Library::AddressOf(T &FunctionDefinition, std::string FunctionName)
{
return (FunctionDefinition = this->AddressOf<T>(FunctionName));
}
template<typename T, typename ...Args>
auto Library::CallFunction(void* Function, Args... args) -> decltype(reinterpret_cast<T>(Function)(args...))
{
return reinterpret_cast<T>(Function)(args...);
}
std::vector<void*> Functions;
typedef void (*Message)(const LPCSTR sometext);
typedef void (*MessageEx)(const LPCSTR sometext, const LPCSTR title);
typedef int (*Add)(int X, int Y);
typedef int (*Subtract)(int X, int Y);
int main()
{
Library L("TestDll.dll");
std::array<std::string, 4> List = {"Message", "MessageEx", "Add", "Sub"};
/** Get Function Addresses.. **/
for (std::size_t I = 0; I < List.size(); ++I)
{
Functions.push_back(L.AddressOf<void*>(List[I]));
}
/** Call Functions.. **/
L.CallFunction<Message>(Functions[0], "Hello World!");
L.CallFunction<MessageEx>(Functions[1], "Hello World!", "DLL MessageBox Title");
std::cout<<L.CallFunction<Add>(Functions[2], 5, 7)<<"\n";
std::cout<<L.CallFunction<Subtract>(Functions[3], 7, 5)<<"\n";
return 0;
}
是否有重新寫我的CallFunction類成員,或者方法以某種方式保留功能的簽名或地圖的功能,其標誌性的名字更好的辦法?我不介意寫出typedef,但我討厭把它們作爲模板參數,以便它可以投射到它,所以如果我能以某種方式使vector載體不同的函數簽名是最好的,但是歡迎任何解決方案。
編輯:爲了清楚起見,我想以某種方式找出它的參數的函數簽名。例如:
//If I do:
CallFunction<int>(FuncPtr, "Subtract", 10, 5);
//It would do:
template<typename T, typename ...Args>
auto Library::CallFunction(void* Function, Args... args) -> decltype(reinterpret_cast<T>(Function)(args...))
{
return //using args, figure out the function signature, call it, and return int.
}
有許多與此極其相似的問題,例如, http://stackoverflow.com/questions/8304582/how-to-store-functional-objects-with-difrent-signature-in-a-container-eg-std和http://stackoverflow.com/questions/4699018/如何對創建-A-容器-保持-不同類型-的函數指針合是c。你確定這不是重複的嗎? – jogojapan
那麼沒有一個是相同的。它的類似,但他們都不想做我心裏想的那個:http://pastebin.com/PFWdr48Z – Brandon