项目中有很多时候用到外部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 代码优化与工程级应用》

dll帮助类的更多相关文章

  1. C#加载dll 创建类对象

    //加载dll 创建类对象string sqlightAssembly = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "syst ...

  2. DLL导出类避免地狱问题的完美解决方案

    DLL动态链接库是程序复用的重要方式,DLL可以导出函数,使函数被多个程序复用,DLL中的函数实现可以被修改而无需重新编译和连接使用该DLL的应用程序.作为一名面向对象的程序员,希望DLL可以导出类, ...

  3. DLL的概念、dll导出类(转贴)

    1. DLL的概念DLL(Dynamic Linkable Library),动态链接库,可以向程序提供一些函数.变量或类.这些可以直接拿来使用.静态链接库与动态链接库的区别:(1)静态链接库与动态链 ...

  4. C++ DLL导出类 知识大全

    在公司使用C++ 做开发,公司的大拿搭了一个C++的跨平台开发框架.在C++开发领域我还是个新手,有很多知识要学,比如Dll库的开发. 参考了很多这方面的资料,对DLL有一个基本全面的了解.有一个问题 ...

  5. c++11实现DLL帮助类

    用过DLL的人都会发现,在C++中调用dll中的函数有点繁琐,调用过程如下:在加载dll后还要定义一个对应的函数指针类型,接着调用GetProcAddress获取函数地址,再转成函数指针,最后调用函数 ...

  6. 通过反射获取DLL的类实现加载窗体

    1.创建一个DLL 类库,并新建一个窗体类,这个直接在vs上操作就好 2. 建立一个Testassembly工程 新建一个测试类 namespace Testassembly { public par ...

  7. DLL 导出类

    MyMathFun.h #pragma once // #ifdef DLLCLASS_API // #define DLLCLASS_API _declspec(dllimport) // #els ...

  8. cmake 静态调用 c++ dll 的类的一个例子(Clion IDE)[更新1:增加1.模版的应用,2.ma 的算法]

    CMakeLists.txt project(aaa) add_library(aaa SHARED aaa.cpp) add_executable(bbb bbb.cpp) target_link_ ...

  9. cmake 静态调用 c++ dll 的类的一个例子(Clion IDE)

    CMakeLists.txt project(aaa) add_library(aaa SHARED aaa.cpp) add_executable(bbb bbb.cpp) target_link_ ...

  10. [百度空间] [原]DLL导出实例化的模板类

    因为模板是在编译的时候根据模板参数实例化的,实例化之后就像一个普通的类(函数),这样才有对应的二进制代码;否则,没有模板参数,那么编译器就不知道怎么生成代码,所以生成的DLL就没有办法导出模板了.但是 ...

随机推荐

  1. TypeScript 学习笔记 — 函数中的类型(四)

    目录 函数的两种声明方式 可选参数 默认参数 剩余参数 函数的重载 this 的类型 对于函数主要关心的是:函数的入参类型 和 函数的返回值类型 函数的两种声明方式 通过 function 关键字来进 ...

  2. 10月11日内容总结——global和nonlocal方法、函数名的多种用法、闭包函数和装饰器

    目录 一.global和nonlocal方法 global方法 nonlocal方法 二.函数名的多种用法 1.函数名可以当作变量名赋值 2.函数名可以当作函数的参数 3.函数名可以当作函数的返回值 ...

  3. LeetCode_单周赛_329

    2544. 交替数字和 代码1 转成字符串,逐个判断 class Solution { public int alternateDigitSum(int n) { char[] s = (" ...

  4. 还不来了解ChatGPT?免费账号

      可以查看这里给大家提供了一些免费的账号供大家尝试 note.youdao.com/s/OvxaLZiF   ChatGPT作为最近火遍互联网的AI项目,获得了大家空前的关注,短短两个多月注册人数破 ...

  5. Illegal mix of collations (latin1_swedish_ci,IMPLICIT) and (utf8_general_ci,COERCIBLE) for operation

    1.出现问题 查询数据时报如题错误 2.解决方案 建表时需指定字符集,例如: -- ---------------------------- -- Table structure for testTa ...

  6. 学习Java Day13

    今天学习了对象与类,类是构造对象的模板或蓝图.由类构造对象的过程称为创建类的实例.类与类之间的关系有依赖,聚合,继承. 然后学习了如何构造对象.

  7. Rigol DSA815频谱仪在合肥光源工作点测量系统中的应用

    发的这篇文,我只是搬运工,读者切记. 合肥光源工作点测量系统已实现BBQ无激励在线测量,还是前些年永良师弟在这的时候调试成功的,并和超才把安捷伦的一台频谱仪和普源的DSA815的IOC调试成功,不过在 ...

  8. 安卓逆向 利用JEB进行动态调试断点 进行内购

    1.第一步肯定是需要配置好,连接到模拟器 2.这个程序会弹出支付失败 所以我们搜索一下关键字 看到这里就很兴奋了 我们取JEB里面对这个方法进行断点 if eqz 等于0 这里 看到那个寄存器是v5 ...

  9. Nacos服务调用(基于Openfeign)

    在<<Nacos服务注册>>这篇文章里,我搭建了一个nacos服务中心,并且注册了一个服务,下面我们来看在上一篇文章的基础上,怎样用Openfeign来调用这个服务. 0.同上 ...

  10. Linux服务器数据备份恢复

    转载csdn: https://blog.csdn.net/weixin_33794672/article/details/92894022