项目中有很多时候用到外部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. 定时任务,LocalDateTime,在代码中调用其他项目的接口url

    1.定时任务 1.在类上添加注解 @Component @Configuration @EnableScheduling 2.在类中方法上添加注解 @Scheduled(cron = "0 ...

  2. ResponseBodyAdvice处理返回数据

    package com.xf.config; import org.slf4j.MDC; import org.springframework.core.MethodParameter; import ...

  3. 安装云崽Bot+GPT3插件

    安装云崽Bot+GPT3插件 这次我们来搭建云崽Bot,云崽Bot其实是一个用于原神的机器人,不过众多大佬开发出了很多有趣的插件供我们使用,这次我们就是用其中的一个插件Chat-gpt(其不是正宗的C ...

  4. 【译】.NET 7 中的性能改进(二)

    原文 | Stephen Toub 翻译 | 郑子铭 堆栈替换 (On-Stack Replacement) 堆栈替换 (OSR) 是 .NET 7 中最酷的 JIT 功能之一.但要真正了解 OSR, ...

  5. 什么是整体设备效率(OEE)?

    整体设备效率 (OEE) 用于监控制造效率.得到的OEE百分比是通用的,可以跨不同行业和流程进行比较. OEE可用性 OEE可用性=实际运行时间/生产时间 OEE可用性是实际运行时间和计划生产时间之间 ...

  6. libco 源码剖析(1): 协程上下文切换之 32 位

    libco 源码剖析(1): 协程上下文切换之 32 位 相关背景资料 关于汇编语言及内存布局相关基础,参看 参考文献[0], 参考文献[1] 32 位协程上下文结构如下: // coctx.h st ...

  7. LAMP环境搭建——最详细的手工编译

    环境:阿里云服务器ECS,Alibaba Cloud Linux 3.2104 LTS 64位 ,2核(vCPU) 2 GiB LAMP 是搭建Web应用时最常用的环境,LAMP 分别表示 Linux ...

  8. 自定义顺序表ArrayList

    1.简介 顺序表是在计算机内存中以数组的形式保存的线性表,线性表的顺序存储是指用一组地址连续的存储单元依次存储线性表中的各个元素.使得线性表中在逻辑结构上相邻的数据元素存储在相邻的物理存储单元中,即通 ...

  9. SQL Server迁移数据库文件(ldf&amp;mdf文件)到其他盘

    为什么 SQL Server安装时,默认都安装在C盘,包括数据库文件的默认位置也是C盘 一般路径是C:/Program Files/Microsoft SQL Server/MSSQL14.MSSQL ...

  10. k8s之service服务

    service服务介绍 在k8s中,pod是应用程序的载体,我们可以通过pod的ip来访问应用程序,但是pod的ip地址不是固定的,这也就意味着不方便直接采用pod的ip对服务进行访问 为了解决这个问 ...