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 ...
随机推荐
- [Linux]经典面试题 - 网络基础 - TCP三次握手
[Linux]经典面试题 - 网络基础 - TCP三次握手 目录 [Linux]经典面试题 - 网络基础 - TCP三次握手 一.TCP报文格式 1.1 TCP报头 1.2 报文图例 二.TCP三次握 ...
- Mac为docker和kubectl添加自动命令补全
我最新最全的文章都在南瓜慢说 www.pkslow.com,欢迎大家来喝茶! 1 前言 自动命令补全是非常有用的功能,特别是当命令有特别多参数时.显然,docker/kubectl就是这样的命令.我们 ...
- 【知识点】SQLite3总结
目录 基本的DDL.DML 创建表,包含日期字段 插入一行,包含日期字段 查找,包含日期字段 查找,按照排序以及限制条目输出 删除记录 更新数据 视图 索引 触发器 事务 专业术语 基本的DDL.DM ...
- 『动善时』JMeter基础 — 50、使用JMeter测试WebSocket接口
目录 1.什么是WebSocket接口 2.为什么需要WebSocket 3.测试WebService接口前的准备 4.WebSocket Sampler组件界面详解 5.使用JMeter测试WebS ...
- 图解 Redis | 差点崩溃了,还好有主从复制
大家好,我是小林哥,又来图解 Redis 啦. 我在前两篇已经给大家图解了 AOF 和 RDB,这两个持久化技术保证了即使在服务器重启的情况下也不会丢失数据(或少量损失). 不过,由于数据都是存储在一 ...
- IDEA搭建一个SpringBoot项目——十分详细(web+mysql)
前排提示: IDEA版本:IntelliJ IDEA 2021.1.1 专业版(是否为专业版影响不大) 搭建目的:前端web页面能够获取到MySQL数据库中的数据 详细步骤: 1. 创建一个新项目 ...
- Redis的数据安全与性能保障
1.持久化选项 Redis提供了2种不同的持久化方法来将数据存储到硬盘里面.一种方法叫快照(snapshotting),它可以将存在于某一时刻的所有数据都写入硬盘里.另一种方法叫只追加文件(appen ...
- 44、djanjo工程(介绍)
44.1.什么时web框架: 1.框架,即framework,特指为解决一个开放性问题而设计的具有一定约束性的支撑结构,使用看框架可以 帮助你快速开发特定的形同,简单的说,就是你用别人搭建好的舞台来做 ...
- liunx驱动之字符设备的注册
上一篇文章学习了如何编写linux驱动,通过能否正常加载模块进行验证是否成功,有做过liunx应用开发的小伙伴都知道驱动会在'/dev'目录下以文件的形式展现出来,所以只是能加载驱动模块不能算是完成驱 ...
- java.lang.Excetion,java.lang.RuntimeException,java.lang.Error有什么区别?
Error类对象由Java虚拟机生成并抛出,Exception类对象由应用程序处理或抛出 Error表示恢复不是不可能但很困难的情况下的一种严重问题.比如说内存溢出.不可能指望程序能处理这样的情况. ...