• 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++的语义细品之后,如此简单!
    都怪自己多年来只顾解决项目问题,忽略了最基础的语义内涵!

  • 相关阅读:
    图床_背景
    图床_摘要
    图床_二维码
    在ubuntu上搭建交叉编译环境---arm-none-eabi-gcc
    在ubuntu上搭建交叉编译环境---arm-none-eabi-gcc
    python的sqlalchemy框架
    python的sqlalchemy框架
    python的sqlalchemy框架
    python的sqlalchemy框架
    烂泥:centos6 yum方式升级内核
  • 原文地址:https://www.cnblogs.com/wuyaSama/p/12452688.html
Copyright © 2020-2023  润新知