一種x64程序使用x86 DLL的方法
阿新 • • 發佈:2018-11-08
一種x64程序使用32位 DLL的方法
測試前記得先註冊COM server
有的時候要用第三方的DLL,但是僅有32位版本,自己開發的程式又必須是是64位的,這下頭就疼了。。。。
其實反之也是一樣的頭疼,這時候有什麼辦法呢?
一個典型的思路就是用32位程序載入DLL,然後64位程序跟32位程序通訊。
其實微軟已經有了COM技術來幫我們解決這個問題:
1.建立一個程序外COM伺服器。
2.使用COM伺服器的相關介面去包裝32位DLL的介面。
3.64位程序呼叫32位COM伺服器介面。
這裡面的關鍵就是如何建立一個程序外COM伺服器
使用ATL模板去建立是一種非常快捷方便的方式
EXE才是程序外Com 服務,另外勾選另一個選項可以減少一個代理project
然後增加一個類作
這時候編譯一下 會發現一個錯誤,
這是因為編譯之後會去註冊com元件,因為沒有許可權兒報錯,如果使用管理員許可權開vs就不會有這個問題。
接著在類中加入包裹DLL的程式碼
STDMETHODIMP CCLeenSimple::LoadDll32() { m_hDll = LoadLibrary(_T("TestDll.dll")); if (m_hDll) { m_pFun = (GCUN)GetProcAddress(m_hDll, "GetCurrentUserName"); if (m_pFun != NULL) return S_OK; } else GetLastError(); return E_FAIL; } STDMETHODIMP CCLeenSimple::Launch(TCHAR szTitile[MAX_PATH]) { HRESULT hr = LoadDll32(); BOOL bRet = FALSE; TCHAR szUserName[MAX_PATH] = { 0 }; if (FAILED(hr)) { OutputDebugString(_T("LoadDll32 fail")); MessageBox(NULL, _T("LoadDll32 fail"), _T("COMServer"), MB_OK); } else { bRet = m_pFun(szUserName); } if (bRet) { OutputDebugString(szUserName); MessageBox(NULL, szUserName, _T("COMServer"), MB_OK); } else { MessageBox(NULL, _T("Func failed"), _T("COMServer"), MB_OK); } return S_OK; }
在IDL檔案中匯出我們的包裝函式
這樣就可以了~
DLL中的函式
EXTERN_C BOOL WINAPI GetCurrentUserName(TCHAR* pszbuff) { BOOL bRet = FALSE; TCHAR szUserNameBuffer[MAX_PATH]; DWORD dwUserNameSize = MAX_PATH; bRet = GetUserName(szUserNameBuffer, &dwUserNameSize); if (bRet) { _tcscpy_s(pszbuff, dwUserNameSize, szUserNameBuffer); } return bRet; }
客戶端測試程式碼
HRESULT hr = CoInitialize(NULL);
ICLeenSimple* pILeenTest;
//CComPtr<ILeenTest> pILeenTest;
TCHAR szUserName[MAX_PATH] = { 0 };
if (SUCCEEDED(hr))
{
hr = CoCreateInstance(CLSID_CLeenSimple, NULL, CLSCTX_LOCAL_SERVER | CLSCTX_REMOTE_SERVER,
__uuidof(ICLeenSimple), (void**)&pILeenTest);
if (SUCCEEDED(hr))
{
pILeenTest->Launch(szUserName);
}
}
測試前記得先註冊COM server
命令
註冊
Out_Process.exe /RegServer
反註冊
Out_Process.exe /UnregServer
可以檢視登錄檔確認是否註冊成功。
執行一下,見證奇蹟的時刻到啦~