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 ...
随机推荐
- 【NX二次开发】获得屏幕矩阵并设置WCS为屏幕方向
说明:获得屏幕矩阵并设置WCS为屏幕方向(Z朝向自己,X轴朝右,Y轴超上). 方法: 1 extern DllExport void ufusr(char *param, int *retcode, ...
- FlinkSQL写入Kafka/ES/MySQL示例-JAVA
一.背景说明 Flink的API做了4层的封装,上两层TableAPI.SQL语法相对简单便于编写,面对小需求可以快速上手解决,本文参考官网及部分线上教程编写source端.sink端代码,分别读取s ...
- HR面试:过五关斩六将后,小心阴沟翻船!(史上最全、避坑宝典)
文章很长,建议收藏起来,慢慢读! 疯狂创客圈为小伙伴奉上以下珍贵的学习资源: 疯狂创客圈 经典图书 : <Netty Zookeeper Redis 高并发实战> 面试必备 + 大厂必备 ...
- Linux安装及管理程序
一,常见的软件包封装类型 二.RPM包管理工具 三.查询RPM软件包信息 四.安装.升级.卸载RPM软件包 五.解决软件包依赖关系的方法 六.源代码编译 七.安装yum源仓库 一,常见的软件包封装类型 ...
- 关于安装运行MYSQL8.0简单使用及注意事项 On Docker Desktop & WSL2
背景介绍 MYSQL是业界非常流行的一款关系型数据库系统,关系数据库将数据保存在不同的表中,而不是将所有数据放在一个大仓库内,这样就增加了速度并提高了灵活性.MySQL所使用的SQL语言是用于访问数据 ...
- 15、nginx编译安装
15.1.nginx介绍: 1.Nginx是一个开源,支持高性能,高并发的www服务和代理服务软件,由俄罗斯人开发,是开源的,nginx因具有高并发(特别是静态的 资源).占用系统资源少等特性,且功能 ...
- 收集雪花(map)
题目描述 不同的雪花往往有不同的形状.在北方的同学想将雪花收集起来,作为礼物送给在南方的同学们.一共有n个时刻,给出每个时刻下落雪花的形状,用不同的整数表示不同的形状.在收集的过程中,同学们不希望有重 ...
- 关于vim
全部删除:按esc后,然后dG全部复制:按esc后,然后ggyG全选高亮显示:按esc后,然后ggvG或者ggVG 在win中使用<C-a>是全选,如果需要在vim中使用<C-a&g ...
- ExtJs4学习(八)数据代理Proxy
ExtJs数据代理我们介绍常用的四种,但会着重介绍ajax代理,因为日常开发中,这个最为常用 Ext.data.proxy.Ajax AjaxProxy(Ajax数据代理类)是你的应用程序中使用最广泛 ...
- python多线程实现方式,最基础的实现方式模块是什么
https://blog.csdn.net/daiyu__zz/article/details/81912018 python3.x中通过threading模块创建新的线程有两种方法:一种是通过thr ...