1. 程式人生 > >一種x64程序使用x86 DLL的方法

一種x64程序使用x86 DLL的方法

一種x64程序使用32位 DLL的方法

有的時候要用第三方的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

可以檢視登錄檔確認是否註冊成功。


執行一下,見證奇蹟的時刻到啦~


程式碼下載連結