64位進程調用32位DLL詳解(利用COM)


https://blog.csdn.net/pathfinder1987/article/details/86093149
https://blog.csdn.net/jaken99/article/details/102815167  

https://blog.csdn.net/liutao_94520/article/details/80803569

 

 

64位進程調用32位DLL------探索
相關資料:
微軟公司的官方網站針對這個問題描述如下:
在64位的windows系統中,一個64位進程不能加載一個32位dll,同理一個32位進程也不能加載一個64位dll。但是,64位windows支持64位和32位進程(包括本機或跨機)間進程間通信(RPC)。在64位windows中,一個進程外32位COM服務器能夠與64位客戶端進行通信,同樣一個進程外64位COM服務器也能與32位客戶端進行通信。因此,如果你有一個32位COM無法識別的DLL,你可以將它封裝到一個進程外COM服務器中並在一個64位進程中用COM配置調用DLL。(最后一句我也看不太懂!!哈哈哈)

驗證:
工作流程:
1.創建一個進程外COM服務器(EXE)。
2.將32位dll的接口函數封裝為COM服務器的相關接口。
3.注冊COM服務器*.exe /regserver  (注銷 *.exe /unregserver)。
4.64位進程調用32位COM服務器接口,成功。從而曲線實現了64位進程調用32位dll。

具體步驟:
創建了一個簡單的32位dll工程,只輸出一個函數int c = Add(int a,int b); 生成lib和dll
然后創建一個進程外COM(EXE類型),添加方法Method: ComServiceAdd(LONG num1, LONG num2, LONG* sum)編譯生成。
然后注冊COM,*.exe /regserver
最后創建一個64位WIN32工程驗證64位環境下方法調用是否正確,經驗證正確!!!

結論:以上方法可以解決64位進程調用32位dll的問題

32位進程調用64位dll應該也可以通過這種方法解決,原因64位windows系統下安裝了32位和64位兩套COM系統
 
實現過程
創建32位DLL
參考:http://blog.csdn.net/nie2314550441/article/details/49782571
[cpp] view plain copy





#ifndef __MY32DLL_H__  
#define __MY32DLL_H__  
  
#ifdef MYLIBDLL  
#define MYLIBDLL extern "C" _declspec(dllimport)   
#else  
#define MYLIBDLL extern "C" _declspec(dllexport)   
#endif  
  
MYLIBDLL int Add(int num1, int num2);  
  
#endif  

 
[cpp] view plain copy





#include "stdafx.h"  
#include "My32Dll.h"  
  
  
MYLIBDLL int Add( int num1, int num2)  
{  
    return num1 + num2;  
}  

 
一、創建COM進程外服務器
        Visual C++ -> ATL -> ATL項目。命名為ComService

 
        選擇 服務(EXE)

至此COM進程外服務器搭建完成
 
在ComServic中添加一個類

在VisualC++ -> ATL -> ATL簡單對象。 類名命名為:SimpleObject 然后一直下一步完成就可以了。
 
添加方法ComServiceAdd
        類視圖 -> ISimpleObject -> 添加 -> 添加方法

 

參數屬性要正確
 
[cpp] view plain copy





#include "stdafx.h"  
#include "SimpleObject.h"  
#include "My32Dll.h"  
  
#pragma comment(lib, "My32Dll.lib")  
  
  
STDMETHODIMP CSimpleObject::ComServiceAdd(LONG num1, LONG num2, LONG* sum)  
{  
    *sum = Add(num1, num2);  
  
    return S_OK;  
}  
COM進程外服務器編寫完成,需要在ComService.exe目錄下添加My32Dll.dll。在實際使用中只需要ComService.exe和My32Dll.dll以及正確的注冊表
 
二、客戶端編寫 ——實現64位程序調用32為DLL
客戶端實現代碼
[cpp] view plain copy





#include "stdafx.h"  
#include <iostream>  
using namespace std;  
  
#include "../../ComService/ComService/ComService_i.h"  
#include "../../ComService/ComService/ComService_i.c"  
  
  
int TestAdd(int num1, int num2, int& sum)  
{  
    CoInitialize( NULL );  
  
    COSERVERINFO si;  
    MULTI_QI     qi;  
  
    ZeroMemory( &si, sizeof( si ) );  
    ZeroMemory( &qi, sizeof( qi ) );  
  
    si.pwszName = L"127.0.0.1";//自己機器的IP  
    si.pAuthInfo = NULL;  
  
    qi.pIID = &IID_ISimpleObject;  
    qi.pItf = NULL;  
  
    long hr = CoCreateInstanceEx(CLSID_SimpleObject, NULL, CLSCTX_REMOTE_SERVER, &si, 1, &qi);  
    if( FAILED( hr ) || FAILED(qi.hr) )  
    {  
        return -1;  //連接服務器失敗  
    }  
  
    ISimpleObject * pT = NULL;  
    qi.pItf->QueryInterface( &pT );  
    qi.pItf->Release();  
  
    long np = pT->ComServiceAdd(num1, num2, (long *)&sum);  
  
  
    pT->Release();  
  
    CoUninitialize();  
}  
  
  
int _tmain(int argc, _TCHAR* argv[])  
{  
  
    int num1 = 10;  
    int num2 = 20;  
    int sum = 0;  
    int np = TestAdd(num1, num2, sum);  
    cout<<"np = "<<np<<endl;  
    cout<<"sum = "<<sum<<endl;  
    return 0;  
}  
 
摘抄自 ComService_i.c
[cpp] view plain copy





MIDL_DEFINE_GUID(IID, IID_ISimpleObject,0xD7EF8D78,0x762B,0x4D93,0x96,0xB0,0xF5,0x8F,0x35,0x2F,0xAE,0x40);  
  
  
MIDL_DEFINE_GUID(IID, LIBID_ComServiceLib,0x047F5BF6,0x73C7,0x4B8B,0x96,0x84,0xDA,0xF2,0xD2,0x52,0x19,0xC4);  
  
  
MIDL_DEFINE_GUID(CLSID, CLSID_SimpleObject,0x2788B4CC,0xFAE2,0x4CD1,0x92,0x9B,0x88,0xBF,0xB6,0x2D,0x14,0xD3);  
 
注冊表:
        由於是在visual studia2008編寫的,vs在編譯的過程中自動添加了注冊表。
        在將工程部署到別的機器上,此時需要添加注冊表,注冊表中服務所指器路徑要和服務器所放位置保存一致
例如,注冊表一部分
[cpp] view plain copy





[HKEY_LOCAL_MACHINE\SOFTWARE\Classes\Wow6432Node\CLSID\{562AD508-3527-437A-BD1A-42BAC379C633}\LocalServer32]  
@="\"<span style="color:#ff0000;">d:\\Jhemr\\JhemrService.exe</span>\""  
[HKEY_CLASSES_ROOT\TypeLib\{9CD121FC-09ED-47C5-BE6D-E5BD6ED4D94A}\1.0\0\win32]  
@="<span style="color:#ff0000;">d:\\Jhemr\\JhemrService.exe</span>"  

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM