64位进程调用32位DLL详解
2015-11-16 19:55
417 查看
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
参考:/article/10714329.html
一、创建COM进程外服务器
Visual C++ -> ATL -> ATL项目。命名为ComService
选择 服务(EXE)
至此COM进程外服务器搭建完成
在ComServic中添加一个类
在VisualC++ -> ATL -> ATL简单对象。 类名命名为:SimpleObject 然后一直下一步完成就可以了。
添加方法ComServiceAdd
类视图 -> ISimpleObject -> 添加 -> 添加方法
参数属性要正确
COM进程外服务器编写完成,需要在ComService.exe目录下添加My32Dll.dll。在实际使用中只需要ComService.exe和My32Dll.dll以及正确的注册表
二、客户端编写 ——实现64位程序调用32为DLL
客户端实现代码
摘抄自 ComService_i.c
注册表:
由于是在visual studia2008编写的,vs在编译的过程中自动添加了注册表。
在将工程部署到别的机器上,此时需要添加注册表,注册表中服务所指器路径要和服务器所放位置保存一致
例如,注册表一部分
相关资料:
微软公司的官方网站针对这个问题描述如下:
在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
参考:/article/10714329.html
#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
#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 -> 添加 -> 添加方法
参数属性要正确
#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
客户端实现代码
#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
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在编译的过程中自动添加了注册表。
在将工程部署到别的机器上,此时需要添加注册表,注册表中服务所指器路径要和服务器所放位置保存一致
例如,注册表一部分
[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>"
相关文章推荐
- 有时候打开eclipse出现error,让看log
- 【转载】Vim查找替换及正则表达式的使用
- 欢迎使用CSDN-markdown编辑器
- 深入浅出 - Android系统移植与平台开发(十一) - Sensor HAL框架分析之一
- sql常用
- matlab中的图像类型
- K-Means++的代码 ,写的很好
- Node.js学习笔记9——Express框架
- 彻底明白Android中AIDL及其使用
- ARM的Abort异常
- IO(一):传统IO(基于字符,字节,Socket) 与BIO,NIO,AIO 介绍
- lightoj1034 Hit the Light Switches
- 硬件语言编写规范与技巧
- hibernate连接Oracle rac
- java笔记_集合
- leetcode 50:Pow(x, n)
- Thread的run()与start()的区别
- xml文件不能被正确解析/The processing instruction target matching "[xX][mM][lL]" is not al
- 图像分割
- HTML笔记(2)