C++模板封装Win32 API 动态调用
起因
花两周通读了一遍《C++ Primer》,积攒的疑惑一扫而光。
前因
利用C++11可变模板,封装调用dll导出函数
本以为已经很好用了,最近抽时间巩固下知识体系,发现自己道行不够!
新方案
充分利用函数模板的实参推断,取得了“近似动态语言”的使用体验。
#include <memory>
#include <utility>
#include <windows.h>
class WinDll
{
public:
explicit WinDll(const char* dll) : mLib(::LoadLibraryA(dll), LibDeleter) {}
explicit WinDll(const wchar_t* dll) : mLib(::LoadLibraryW(dll), LibDeleter) {}
operator bool() { return !!mLib.get(); }
template <typename Ret, typename... Args>
Ret Invoke(const char* name, Args&& ...args)
{
auto proc = GetProcAddress(reinterpret_cast<HMODULE>(mLib.get()), name);
typedef Ret(__stdcall* Func)(Args...);
return (proc) ? reinterpret_cast<Func>(proc)(std::forward<Args>(args)...) : (Ret());
}
private:
std::shared_ptr<void> mLib;
static void LibDeleter(HMODULE h) { if (h) FreeLibrary(h); }
};
int main()
{
WinDll user32("user32");
if (user32) {
user32.Invoke<int>("MessageBoxA", 0, 0, 0, 0);
WinDll user32Copy = user32;
user32Copy.Invoke<int>("MessageBoxW", NULL, L"Hello World!", L"Demo", MB_ICONINFORMATION | MB_OK);
}
}
感想
C++的语义细品之后,如此简单!
都怪自己多年来只顾解决项目问题,忽略了最基础的语义内涵!
C++模板封装Win32 API 动态调用的更多相关文章
- 如何封装使用api形式调用的vue组件
在实际开发中一般有两种封装vue组件的方法:一种就是常用的的通过props父组件传值给子组件的方法: 子组件 父组件: 还有一种就是通过调用api的形式,下面例子是本人在实际项目中封装的一个自定义图标 ...
- 动态调用DLL函数有时正常,有时报Access violation的异常
动态调用DLL函数有时正常,有时报Access violation的异常 typedef int (add *)(int a,int b); void test() { hInst=LoadL ...
- C#调用Win32 api学习总结
从.NET平台调用Win32 API Win32 API可以直接控制Microsoft Windows的核心,因为API(Application Programming Interface)本来就是微 ...
- MSIL 教程(二):数组、分支、循环、使用不安全代码和如何调用Win32 API(转)
转自:http://www.cnblogs.com/Yahong111/archive/2007/08/16/857574.html 续上文[翻译]MSIL 教程(一) ,本文继续讲解数组.分支.循环 ...
- Python调用win32 API绘制正弦波
Python调用win32 API新建窗口与直接创建窗口的流程相同 流程:注册窗口→创建窗口→显示窗口→更新窗口→消息循环 代码: # -*- coding: utf-8 -*- import win ...
- C#调用Win32 api时的内存操作
一般情况下,C#与Win 32 Api的互操作都表现的很一致:值类型传递结构体,一维.二维指针传递IntPtr.在Win32 分配内存时,可以通过IntPtr以类似移动指针的方式读取内存.通过IntP ...
- nodejs 调用win32 api
video 教程文件 win32 api >node -v v12.16.1 >npm install -g node-gyp >npm i @saleae/ffi >node ...
- C#程序实现动态调用DLL的研究(转)
摘 要:在<csdn开发高手>2004年第03期中的<化功大法——将DLL嵌入EXE>一文,介绍了如何把一个动态链接库作为一个资源嵌入到可执行文件,在可执行文件运行时,自动从资 ...
- C#动态调用C++编写的DLL函数
C#动态调用C++编写的DLL函数 动态加载DLL需要使用Windows API函数:LoadLibrary.GetProcAddress以及FreeLibrary.我们可以使用DllImport在C ...
随机推荐
- 【creo】CREO5.0+VS2019配置(还没写完)
欢迎大家一起学习使用c++对CREO5.0二次开发. 第1步,建立开发目录:在E盘(或者其他盘)新建creo_cpp文件夹,文件夹中新建ABC_TOOLS用来存放我们开发的工具,CODE文件夹存放开发 ...
- dos脚本语法学习
一个dos批处理脚本,通过关键字搜索注册表并删除,坑很多,语法也很怪异,详情看注释 @echo off ::声明采用UTF-8编码,避免中文乱码问题,>NUL可以吞掉chcp输出的内容 chcp ...
- JavaScript的介绍概括
1.js是一种轻型的解释性的脚本语言,称为web脚本语言. 2.js的执行原理:当客户端向服务器端请求某个页面时,浏览器端将整个页面中包含JavaScript的脚本代码作为响应内容,发送到客户端的机器 ...
- ffmpeg入门到实战-ffmpeg是怎么转码的?
阅读目录 视频是怎么被播放的? ffmpeg命令的格式 ffmpeg转码输出的过程 视频是怎么被播放的? 我们知道,当下大多数播放器都是基于ffmpeg二次开发的.你有没有想过,你用播放器打开一个视频 ...
- 大白话spring依赖注入
在前边的文章中分享了spring如何实现属性的注入,有注解和配置文件两种方式,通过这两种方式可以实现spring中属性的注入,具体配置可查看<spring入门(一)[依赖注入]>,那么sp ...
- 第二篇CTF-MISC
第一篇写成了日记,发布不了.第一篇CTF-MISC 04.坚持60S 附件下载下来,是个jar的文件,打开 耶?这是嘛呀? 反正没看懂,既然是jar文件,直接上jd-gui反编译一波试试 这么明显的f ...
- 精尽Spring Boot源码分析 - 剖析 @SpringBootApplication 注解
该系列文章是笔者在学习 Spring Boot 过程中总结下来的,里面涉及到相关源码,可能对读者不太友好,请结合我的源码注释 Spring Boot 源码分析 GitHub 地址 进行阅读 Sprin ...
- 13、ssh跳板机
13.1.前提条件: 1.跳板机服务器和其它服务器建立了ssh秘钥登录: 2.目前的环境: (1)各服务器上都建立了lc用户,并给于sudo (lc ALL= NOPASSWD:ALL )权限,lc就 ...
- POJ 1556 计算几何 判断线段相交 最短路
题意: 在一个左下角坐标为(0,0),右上角坐标为(10,10)的矩形内,起点为(0,5),终点为(10,5),中间会有许多扇垂直于x轴的门,求从起点到终点在能走的情况下的最短距离. 分析: 既然是求 ...
- jenkins pipeline构建后返回构建结果给gitlab
jenkins pipeline构建后返回构建结果给gitlab 使用场景 gitlab 合并请求时要求管道任务必须成功,否则无法执行合并操作,又不想使用gitlab ci 工具. 实现方法 1.Ge ...