c++11实现DLL帮助类
用过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帮助类的更多相关文章
- C#加载dll 创建类对象
//加载dll 创建类对象string sqlightAssembly = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "syst ...
- DLL导出类避免地狱问题的完美解决方案
DLL动态链接库是程序复用的重要方式,DLL可以导出函数,使函数被多个程序复用,DLL中的函数实现可以被修改而无需重新编译和连接使用该DLL的应用程序.作为一名面向对象的程序员,希望DLL可以导出类, ...
- DLL的概念、dll导出类(转贴)
1. DLL的概念DLL(Dynamic Linkable Library),动态链接库,可以向程序提供一些函数.变量或类.这些可以直接拿来使用.静态链接库与动态链接库的区别:(1)静态链接库与动态链 ...
- C++ DLL导出类 知识大全
在公司使用C++ 做开发,公司的大拿搭了一个C++的跨平台开发框架.在C++开发领域我还是个新手,有很多知识要学,比如Dll库的开发. 参考了很多这方面的资料,对DLL有一个基本全面的了解.有一个问题 ...
- 通过反射获取DLL的类实现加载窗体
1.创建一个DLL 类库,并新建一个窗体类,这个直接在vs上操作就好 2. 建立一个Testassembly工程 新建一个测试类 namespace Testassembly { public par ...
- 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_ ...
- DLL 导出类
MyMathFun.h #pragma once // #ifdef DLLCLASS_API // #define DLLCLASS_API _declspec(dllimport) // #els ...
- [C++ Primer Plus] 第11章、使用类(一)程序清单——重载 P408
程序清单11.4~11.6(运算符重载——添加加法运算符) //1.h class Time { private: int hours; int minutes; public: Time(); Ti ...
- Cuder - 用C++11封装的CUDA类
以前写cuda:初始化环境,申请显存,初始化显存,launch kernel,拷贝数据,释放显存.一个页面大部分都是这些繁杂但又必须的操作,有时还会忘掉释放部分显存. 今天用C++11封装了这些CUD ...
随机推荐
- BZOJ——1606: [Usaco2008 Dec]Hay For Sale 购买干草
http://www.lydsy.com/JudgeOnline/problem.php?id=1606 Time Limit: 5 Sec Memory Limit: 64 MBSubmit: 1 ...
- Fragment 生命周期怎么来的?
前言 Fragment对于 Android 开发人员来说一点都不陌生,由于差点儿不论什么一款 app 都大量使用 Fragment,所以 Fragment 的生命周期相信对于大家来说应该都非常清晰.但 ...
- malloc动态分配多维数组
下面试自己写的三个测试程序,如果看懂了基本上动态分配多维数组就没什么问题啦:重点 1:深刻理解多维数组的概念,多维数组在内存中的分配情况,基本上动态分配也没什么问题的.然后还要注意一点的就是,释放是分 ...
- Apatch常用的commons工具包介绍
1.Commons BeanUtils http://jakarta.apache.org/commons/beanutils/index.html 说明:针对Bean的一个工具集.由于Bean往往是 ...
- Android 特别大的Activity和Fragment的生命周期图
这么 这么大的图.不做太多解释,哈哈,真的是棒棒的. 代码測试下载:http://download.csdn.net/detail/pcaxb/8906085
- homebrew -v 或homebrew -doctor报错请检查 .bash_profile是否有误
homebrew -doctor报错: /usr/local/Library/Homebrew/global.rb:109:in `split': invalid byte sequence in U ...
- Creating a .bash_profile on your mac
A typical install of OS X won't create a .bash_profile for you. When you want to run functions from ...
- jquery一个比较好的轮播图jQuery.kinMaxShow介绍
kinMaxShow API 可选参数以及详解 kinMaxShow 主参数详解 参数名称 默认值 简单释义 height 500 [整型 (单位:像素)]焦点图高度,必须设置 缺省则启用默认高度 5 ...
- 使用JWT设计SpringBoot项目api接口安全服务
转载直: 使用JWT设计SpringBoot项目api接口安全服务
- hadoop yarn namenode datanoe 启动异常问题解决 分析日志
cat logs/hadoop-root-datanode-hadoop1.log ********************************************************** ...