封裝統一模板調用動態庫(dll)


enum CallLibType
{
    eStdCall,
    eCdecl
};

template<typename ResultType, typename ...params>
void  CallLibrary(CallLibType eType, std::string strDll, std::string strFuncName, ResultType& ret, params... para)
{
    HMODULE hd = LoadLibraryA(strDll.c_str());

    if (0 == hd) return;
    if (eStdCall == eType)
    {
        typedef ResultType(__stdcall *FuncType)(params...);
        FuncType func = (FuncType)GetProcAddress(hd, strFuncName.c_str());
        if (func != NULL)
        {
            ret = func(para...);
        }
    }
    else if(eCdecl == eType)
    {
        typedef ResultType(__cdecl *FuncType)(params...);
        FuncType func = (FuncType)GetProcAddress(hd, strFuncName.c_str());
        if (func != NULL)
        {
            ret = func(para...);
        }
    }
    FreeLibrary(hd);
}

測試代碼

int main()
{
    BOOL bRet = FALSE;

    OSVERSIONINFOA os = { 0 };
    ZeroMemory(&os, sizeof(OSVERSIONINFOA));
    os.dwOSVersionInfoSize = sizeof(OSVERSIONINFOA);

    CallLibrary<BOOL>(eStdCall, "kernel32.dll", "GetVersionExA", bRet, &os);
    std::cout << "bRet = " << bRet << std::endl;
    std::cout << "dwMajorVersion = " << os.dwMajorVersion << std::endl;
    std::cout << "dwMinorVersion = " << os.dwMinorVersion << std::endl;
    std::cout << "dwBuildNumber = " << os.dwBuildNumber << std::endl;
    std::cout << "dwPlatformId = " << os.dwPlatformId << std::endl;
    std::cout << "szCSDVersion = " << os.szCSDVersion << std::endl;

    CHAR buff[512] = { 0 };

    DWORD dRet = 0;
    CallLibrary<DWORD>(eStdCall, "kernel32.dll", "GetModuleFileNameA", dRet, NULL, buff, 512);
    std::cout << std::endl;
    std::cout << "dRet = " << dRet << std::endl;
    std::cout << "buff = " << buff << std::endl;

    return 0;

}

測試結果

 

拋磚引玉,可以再定製一個無返回值的版本。其他調用約定類型可以自行添加。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章