起因

花两周通读了一遍《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 动态调用的更多相关文章

  1. 如何封装使用api形式调用的vue组件

    在实际开发中一般有两种封装vue组件的方法:一种就是常用的的通过props父组件传值给子组件的方法: 子组件 父组件: 还有一种就是通过调用api的形式,下面例子是本人在实际项目中封装的一个自定义图标 ...

  2. 动态调用DLL函数有时正常,有时报Access violation的异常

    动态调用DLL函数有时正常,有时报Access violation的异常 typedef int (add *)(int a,int b); void test() {     hInst=LoadL ...

  3. C#调用Win32 api学习总结

    从.NET平台调用Win32 API Win32 API可以直接控制Microsoft Windows的核心,因为API(Application Programming Interface)本来就是微 ...

  4. MSIL 教程(二):数组、分支、循环、使用不安全代码和如何调用Win32 API(转)

    转自:http://www.cnblogs.com/Yahong111/archive/2007/08/16/857574.html 续上文[翻译]MSIL 教程(一) ,本文继续讲解数组.分支.循环 ...

  5. Python调用win32 API绘制正弦波

    Python调用win32 API新建窗口与直接创建窗口的流程相同 流程:注册窗口→创建窗口→显示窗口→更新窗口→消息循环 代码: # -*- coding: utf-8 -*- import win ...

  6. C#调用Win32 api时的内存操作

    一般情况下,C#与Win 32 Api的互操作都表现的很一致:值类型传递结构体,一维.二维指针传递IntPtr.在Win32 分配内存时,可以通过IntPtr以类似移动指针的方式读取内存.通过IntP ...

  7. nodejs 调用win32 api

    video 教程文件 win32 api >node -v v12.16.1 >npm install -g node-gyp >npm i @saleae/ffi >node ...

  8. C#程序实现动态调用DLL的研究(转)

    摘 要:在<csdn开发高手>2004年第03期中的<化功大法——将DLL嵌入EXE>一文,介绍了如何把一个动态链接库作为一个资源嵌入到可执行文件,在可执行文件运行时,自动从资 ...

  9. C#动态调用C++编写的DLL函数

    C#动态调用C++编写的DLL函数 动态加载DLL需要使用Windows API函数:LoadLibrary.GetProcAddress以及FreeLibrary.我们可以使用DllImport在C ...

随机推荐

  1. ABAP SORT排序注意点

    SORT TABLE BY XXX XXX .如果不加任何语法都是默认升序,延伸可以用ASCENDING和DESCENDING对具体的字段进行升序和降序排列. 简单通俗的来阐释一下,在字段名后面加AS ...

  2. MySQL进阶:主主复制+Keepalived高可用

    Blog:博客园 个人 概述 mysql主主复制 所谓主主复制,即双主备份,或者叫互作主从复制,每台master既是master,又是slave.这种方案,既做到了访问量的压力分流,同时也解决了单点故 ...

  3. 生成树协议(STP)

    一.交换网络环路的产生 1.广播风暴的形成 2.多帧复制 3.MAC地址表紊乱 二.STP简介 STP-Spanning Tree Protocol(生成树协议) 逻辑上断开环路,防止广播风暴的产生 ...

  4. Java IO学习笔记八:Netty入门

    作者:Grey 原文地址:Java IO学习笔记八:Netty入门 多路复用多线程方式还是有点麻烦,Netty帮我们做了封装,大大简化了编码的复杂度,接下来熟悉一下netty的基本使用. Netty+ ...

  5. hash表及带注释插头dp

    struct hash_map { node s[SZ+10];int e,adj[SZ+10]; inline void init(){e=0;memset(adj,0,sizeof(adj));} ...

  6. Java 读取Word表格中的文本和图片

    本文通过Java程序来展示如何读取Word表格,包括读取表格中的文本和图片.下面是具体实现的步骤和方法. 1. 程序环境准备 代码编译工具:IntelliJ IDEA Jdk版本:1.8.0 测试文档 ...

  7. 使用Dice loss实现清晰的边界检测

    ​ 前言: 在深度学习和计算机视觉中,人们正在努力提取特征,为各种视觉任务输出有意义的表示.在一些任务中,我们只关注对象的几何形状,而不管颜色.纹理和照明等.这就是边界检测的作用所在. 关注公众号CV ...

  8. centos 8 下解压.tar.gz文件

    执行命令 tar 参数 文件名 参数: -c :建立一个压缩文件的参数指令(create 的意思): -x :解开一个压缩文件的参数指令: -t :查看 tarfile 里面的文件: 特别注意,在参数 ...

  9. CentOS查看和修改PATH环境变量的方法 (转)

      查看PATH:echo $PATH以添加mongodb server为列修改方法一:export PATH=/usr/local/mongodb/bin:$PATH//配置完后可以通过echo $ ...

  10. ESP32的ULP 协处理器笔记

    1.ULP 协处理器是一个功耗极低的协处理器设备,无论主 CPU 是处于正常运行模式还是 Deep-sleep 模式,ULP 协处理器都可以独立运行.超低功耗协处理器的补充使得 ESP32 能够胜任一 ...