dll帮助类
项目中有很多时候用到外部dll,调用的时候如果用静态调用,程序exe目录下有很多dll,看起来很乱,不利于后续维护;动态调用可以把dll放在想放的文件夹内,但是如果一个dll要用到的函数很多,动态调用就会很麻烦。采用可变参数模板类可以让动态调用变得像静态调用一样。
注:仅在支持C++11的IDE下使用。
//.h #include<Windows.h> #include<iostream> #include <string> #include <map> #include <functional> using namespace std; class CDllParser { public: CDllParser(); ~CDllParser(); bool Load(const char* dllPath); bool unLoad(); template <typename T> std::function<T> getFunction(const char* funcName); template <typename T, typename... Args> typename std::result_of<std::function<T>(Args...)>::type excecuteFunc(const char* funcName, Args&&... args); private: HMODULE m_hMod; std::map<string, FARPROC> m_map; }; template <typename T> std::function<T> CDllParser::getFunction(const char* funcName) { auto it = m_map.find(funcName); if (it == m_map.end()) { auto addr = GetProcAddress(m_hMod, funcName); if (nullptr == addr) return nullptr; m_map.insert(std::make_pair(funcName, addr)); it = m_map.find(funcName); } return std::function<T>((T*)(it->second)); } template <typename T, typename... Args> typename std::result_of<std::function<T>(Args...)>::type CDllParser::excecuteFunc(const char* funcName, Args&&... args) { auto f = getFunction<T>(funcName); if (nullptr == f) { string s = "Can not find function "; s.append(funcName); throw std::exception(s.c_str()); } return f(std::forward<Args>(args)...); }
//.cpp #include "StdAfx.h" #include "CallDLL.h" CDllParser::CDllParser() :m_hMod(nullptr) { } CDllParser::~CDllParser() { unLoad(); } bool CDllParser::Load(const char* dllPath) { m_hMod = LoadLibrary(dllPath); if (nullptr == m_hMod) return false; return true; } bool CDllParser::unLoad() { if (nullptr == m_hMod) return true; auto bFree = FreeLibrary(m_hMod); if (!bFree) return false; m_hMod = nullptr; return true; }
参考:《深入应用C++11 代码优化与工程级应用》