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 ...
随机推荐
- HDU - 5974 A Simple Math Problem (数论 GCD)
题目描述: Given two positive integers a and b,find suitable X and Y to meet the conditions: X+Y=a Least ...
- P1339 热浪Heat Wave 洛谷
https://www.luogu.org/problem/show?pid=1339 题目描述 The good folks in Texas are having a heatwave this ...
- centos 下完全卸载 mysql5.6
查看已经安装的服务 rpm –qa|grep -i mysql -i 作用是不区分大小写 yum remove mysql mysql-server mysql-libs compat-mysql51 ...
- C# 把控件内容导出图片
Bitmap newbitmap = new Bitmap(panelW.Width, panelW.Height); panelW.DrawToBitmap(newbitmap ...
- MyReport报表引擎1.2.0.1新功能
一维码(Code128B)转换显示. 多联标题. 修正BugSum统计函数问题报表编辑器保存时没有生成新加入的单元格相关的xml数据 相关链接MyReport演示.产品站点 相关文章MyReport ...
- xgboost原理及并行实现
XGBoost训练: It is not easy to train all the trees at once. Instead, we use an additive strategy: fix ...
- 制作ubuntu U盘安装盘
sudo dd if=ubuntu.iso of=/dev/sdb2 sudo syslinux /dev/sdb1
- linux 环境 php 链接 sqlserver 2008
说明 由于业务需要 在 linux 系统下的 PHP 环境中 要链接 sqlserver2008 数据库 . 添加PHP 链接数据库扩展 php-mssql dockerfile FROM hub.0 ...
- 多线程网页爬虫 python 实现(二)
#!/usr/bin/env python #coding=utf-8 import threading import urllib import re import time cur=0 last= ...
- nginx-伤心的事
今天测试接口,总是出问题,测试了两天,整个流程就卡在最后一步. 每次采用curl,request等请求访问我的服务器都会返回403状态码,网上找了很多资料 有权限的,有静态文件的,然而很多都没有什么卵 ...