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 ...
随机推荐
- css3 nth-child 与 nth-of-type 的区别
by zhangxinxu from http://www.zhangxinxu.com本文地址:http://www.zhangxinxu.com/wordpress/?p=1709 一.深呼吸,直 ...
- Delphi中的操作二进制文件的两个重要函数
Delphi中的操作二进制文件的两个重要函数 对于通过Byte数组进行文件操作的,在FTP中经常会使用到,我也是在Delphi调用Web Service进行文件的上传和下载时找到这两个函数的,挺好用的 ...
- vue之监听事件
一.v-on 可以用 v-on 指令监听 DOM 事件,并在触发时运行一些 JavaScript 代码. 简写形式 用@代替 v-on: <button v-on:click="co ...
- 模板题 Problem I Link Cut Tree
@(XSY)[LCT] Description 你们这么轻松A了前两题,要是AK了我可就惨了,所以这道题一定要是难(shui)题.那出什么难题呢?有了,这样吧,第一题是数,第二题是树,那我就出个同时含 ...
- 解决asp.net core 日期格式 datetime Json返回 带T的问题
原文:解决asp.net core 日期格式 datetime Json返回 带T的问题 记录一下: Startup中,将 services.AddMvc(); 改为: services.AddMvc ...
- js如何获取table或者ul中鼠标点的行号和内容
<html> <head> <script language="javascript"> function doclick() { var td ...
- Java笔试面试题007
Java笔试面试题007 1.请用正則表達式匹配出QQ号(如果QQ号码为5-10位). 解答: ^ \d{5,10}$ 2.String, StringBuffer StringBuilder的差别. ...
- EF使用自定义字符串连接数据库
edmx的构造函数: public TestCheckUpdatesEntities(): base(Config.DataBaseConnectionString(), "TestChec ...
- Java集合框架:Arrays工具类
java.util.Arrays类能方便地操作数组,它提供的方法都是静态的.整个Arrays工具类的实现有3000+行.可是归纳总结一下可知它有下面功能(9个): 1. asList 定义: @Saf ...
- Django-权限信息自定义标签
自定义权限标签: import re from django.template import Library from django.conf import settings register = L ...