用过DLL的人都会发现,在C++中调用dll中的函数有点繁琐,调用过程如下:在加载dll后还要定义一个对应的函数指针类型,接着调用GetProcAddress获取函数地址,再转成函数指针,最后调用函数。如果一个dll中有上百个函数,这中繁琐的定义会让人不胜其烦,下面将使用C++新特性中的多参数模版、function和type_traits结合起来山西爱你一个通用的dll帮助类。

1. win32 dll创建

1.1 mydll.h

#ifdef MYDLL_EXPORTS
#define MYDLL_API __declspec(dllexport)
#else
#define MYDLL_API __declspec(dllimport)
#endif extern "C" MYDLL_API int Add(int, int);
extern "C" MYDLL_API float MultParmFun(int, float, char*);

1.2 mydll.cpp

#include "stdafx.h"
#include "mydll.h" #include <iostream>
using namespace std; MYDLL_API int Add(int a, int b)
{
cout << "entered:" << __FUNCTION__ << endl;
cout << "参数分别为:" << a << " "<< b << endl;
return a + b;
} MYDLL_API float MultParmFun(int a, float b, char* pBuff)
{
cout << "entered:" << __FUNCTION__ << endl;
cout << "参数分别为:" << a << " " << b << " "<< pBuff<< endl;
if (!pBuff)
{
return .;
} return a * b;
}

2. dll导出函数调用一般方法

#include "stdio.h"
#include <windows.h>
#include <string>
#include <codecvt>
#include <iostream>
using namespace std; string UncodeToAnsi(wstring &wstr)
{
wstring_convert<codecvt<wchar_t, char, mbstate_t>> convert(new codecvt<wchar_t, char, mbstate_t>("CHS"));
return convert.to_bytes(wstr);
} wstring AnsiToUnicode(string &str)
{
wstring_convert<codecvt<wchar_t, char, mbstate_t>> convert(new codecvt<wchar_t, char, mbstate_t>("CHS"));
return convert.from_bytes(str);
} void main()
{
HMODULE hMode = LoadLibrary(L"mydll");
if (!hMode)
{
return;
} typedef int(*Add)(int, int);
wstring wstr = L"Add";
string str = UncodeToAnsi(wstr);
Add AddFun = (Add)GetProcAddress(hMode, str.c_str());
cout << AddFun(, ) << endl; typedef float(*MultParm)(int, float, char*);
wstring wstr1 = L"MultParmFun";
string str1 = UncodeToAnsi(wstr1);
MultParm MultParmFun = (MultParm)GetProcAddress(hMode, str1.c_str());
cout << MultParmFun(, , "helloworld") << endl;
}

3. DLL帮助类的实现

3.1 代码实现

#pragma once

/*
DLL函数调用帮助类 实现的关键:
如何将一个FARPROC变成一个函数指针赋值给function,然后再调用可变参数执行,
函数的返回值通过std::result<function<T>(ARGS...)>来泛化,使得不同的dll
函数都可以用相同的方法来调用 需解决以下几个问题:
1.函数定义
2.函数调用多参数
3.返回值
*/ #include<functional>
#include<string>
using namespace std; #include "mydll.h"
#include <windows.h> bool InitDllHandle(HMODULE &hModule)
{
hModule = LoadLibrary(L"mydll");
if (!hModule)
{
return false;
}
return true;
} template<typename T>
function<T> GetFunction(HMODULE &hModule, string &strFunName)
{
FARPROC funAddress= (FARPROC)GetProcAddress(hModule, strFunName.c_str()); return function<T>((T*)funAddress);
} template<typename T, typename ...ARGS>
typename result_of<function<T>(ARGS...)>::type ExcecuteFunc(HMODULE &hModule, string &strFunName, ARGS ...args)
{
function<T> fun = GetFunction<T>(hModule, strFunName);
return fun(args...);
}

3.2 测试

#include "stdio.h"

#include "DllHelper.h"

#include <string>
#include <codecvt>
#include <iostream>
using namespace std; string UncodeToAnsi(wstring &wstr)
{
wstring_convert<codecvt<wchar_t, char, mbstate_t>> convert(new codecvt<wchar_t, char, mbstate_t>("CHS"));
return convert.to_bytes(wstr);
} wstring AnsiToUnicode(string &str)
{
wstring_convert<codecvt<wchar_t, char, mbstate_t>> convert(new codecvt<wchar_t, char, mbstate_t>("CHS"));
return convert.from_bytes(str);
} void main()
{
HMODULE hMoudle;
bool bResult = InitDllHandle(hMoudle);
if (!bResult)
{
cout << "句柄为空!" << endl;
}
string str = "Add";
int a = ExcecuteFunc<int(int, int)>(hMoudle, str, , );
string str1 = "MultParmFun";
float b = ExcecuteFunc<float(int,float,char*)>(hMoudle, str1, , 3.2, (char *)"helloworld");
}

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. 通过反射获取DLL的类实现加载窗体

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

  6. 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_ ...

  7. DLL 导出类

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

  8. [C++ Primer Plus] 第11章、使用类(一)程序清单——重载 P408

    程序清单11.4~11.6(运算符重载——添加加法运算符) //1.h class Time { private: int hours; int minutes; public: Time(); Ti ...

  9. Cuder - 用C++11封装的CUDA类

    以前写cuda:初始化环境,申请显存,初始化显存,launch kernel,拷贝数据,释放显存.一个页面大部分都是这些繁杂但又必须的操作,有时还会忘掉释放部分显存. 今天用C++11封装了这些CUD ...

随机推荐

  1. 使用SourceTree 来管理 Gitcafe 的Pages 发布Blog!

    有个好爹的 SourceTree 是来自 JIRA 的娘家 Bitbucket 的新东家 ATLASSIAN.com 一家成功的,对敏捷软件工程拥有全栈式支持的商业公司, 所推出的 MAC 专用, S ...

  2. yum gd linux

    32位操作系统安装命令:[root@localhost ~]# yum install php-gd*64位操作系统安装命令:[root@localhost ~]# yum install php-g ...

  3. 深入理解javascript之设计模式

    设计模式 设计模式是命名.抽象和识别对可重用的面向对象设计实用的的通用设计结构. 设计模式确定类和他们的实体.他们的角色和协作.还有他们的责任分配. 每个设计模式都聚焦于一个面向对象的设计难题或问题. ...

  4. 标C编程笔记day04 预处理、宏定义、条件编译、makefile、结构体使用

    预处理:也就是包括须要的头文件,用#include<标准头文件>或#include "自己定义的头文件" 宏定义,如:#define PI 3.1415926 查看用宏 ...

  5. 全国省市区三级联动js

    function Dsy(){ this.Items = {}; } Dsy.prototype.add = function(id,iArray){ this.Items[id] = iArray; ...

  6. Mmseg中文分词算法解析

    Mmseg中文分词算法解析 @author linjiexing 开发中文搜索和中文词库语义自己主动识别的时候,我採用都是基于mmseg中文分词算法开发的Jcseg开源project.使用场景涉及搜索 ...

  7. Android 关于BottomDialogSheet 与Layout擦出爱的火花?

    今天上班做那个相似于ios拍照的那种效果图 就是个垂直布局然后里面textview+切割线+textview+button 当然也能够用button+切割线+button 方法有非常多,选择适合自己的 ...

  8. 前端编程提高之旅(五)----写给大家看的css书

       自实习也有几个月的时间了,以爱奇艺实习为敲门砖.进入了眼下这家公司.假设说当初能进爱奇艺是暂时袭击DIV+CSS的话,眼下在这家公司体验到.不论什么技术都必须悉知原理,这样才干做到庖丁解牛.做一 ...

  9. Comparable 和 Comparator的理解

    对Comparable 的解释 Comparable是一个排序接口 此接口给实现类提供了一个排序的方法,此接口有且只有一个方法 public int compareTo(T o); compareTo ...

  10. HDOJ1006

    #include <cstdio>#include <algorithm>using namespace std;const double UB=43200;const dou ...