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++的语义细品之后,如此简单!

都怪自己多年来只顾解决项目问题,忽略了最基础的语义内涵!