64位进程调用32位DLL的解决方法

本文详细介绍了在64位Windows系统下,如何通过创建进程外COM服务器来实现64位进程调用32位DLL的方法。通过封装32位DLL为COM服务器接口,并在64位环境中注册和调用,成功解决了跨位数DLL调用难题。

64位进程调用32DLL的解决方法

最近做在Windows XP X64VS2005环境下,32位程序编译为64位程序的工作,遇到了一些64位编程中可能遇到的问题:如内联汇编(解决方法改为C/C++代码),long类型的变化,最关键的遇到了64位进程需要调用32DLL的问题。由于有一些32DLL没有源代码,无法重新编译为64DLL,所以只能想办法解决64位进程调用32DLL问题,这个问题让我很是挠头了几天。

微软公司的官方网站针对这个问题描述如下:

64位的Windows系统中,一个64位进程不能加载一个32DLL,同理一个32位进程也不能加载一个64DLL。但是,64Windows支持64位和32位进程间(包括本机或跨机)进程间通信(RPC)。在64Windows中,一个进程外32COM服务器能够与64位客户端进行通信,同样一个进程外64COM服务器也能与32位客户端进行通信。因此,如果你有一个32COM无法识别的DLL,你可以将它封装到一个进程外COM服务器中并在一个64位进程中用COM配置调用DLL

工作流程:

  1. 创建一个进程外COM服务器(EXE)。
  2. 32DLL的接口函数封装为COM服务器的相关接口。
  3. 注册COM服务器*.exe /regserver (注销 *.exe /unregserver)
  4. 64位进程调用32COM服务器接口,成功。从而曲线实现了64位进程调用32DLL

具体步骤:

首先创建了一个简单的DLL工程,只输出一个函数

int c = add(int a,int b);

生成libdll

然后创建一个进程外COM(EXE类型),内部链接dll,添加方法

Method: Add(long *c)

{ *c = add(1,2);}

编译生成。

然后注册COM*.exe /regserver

最创建一个64WIN32工程验证64位环境下方法调用是否正确,经验证正确!

结论:以上方法可以解决64位进程调用32DLL的问题

<think>好的,我现在要解决的问题是Java 64进程如何调用32DLL。首先,我需要理解为什么会出现这个问题。Java是跨平台的,但是当涉及到本地库时,比如Windows的DLL,就必须考虑架构匹配的问题。64的Java进程只能加载64DLL,而32DLL不能被直接加载,这会导致UnsatisfiedLinkError。所以,用户的问题是希望让64的Java进程调用32DLL,这就需要找到一种方法解决架构不匹配的问题。 接下来,我需要思考可能的解决方案。常见的解决方法可能有几种。第一种是使用中间进程,比如创建一个32的代理进程,通过进程间通信(IPC)让64的Java进程与这个代理通信,由代理加载32DLL并执行操作。第二种是使用JNI桥接,但同样需要32的JVM,这可能不现实。第三种是使用一些桥接工具或库,比如JNA或JNI的包装器,但可能需要额外的配置。 然后,我需要评估每种方法的可行性。使用中间进程方法似乎比较可行,因为它避免了直接加载32DLL64进程的问题。例如,可以编写一个32的C++程序,作为服务运行,监听来自Java进程的请求,然后调用DLL的函数,并将结果返回。Java进程可以通过Socket、命令行调用或者命名管道等方式与这个代理通信。 接下来,考虑具体实现步骤。假设选择使用命令行调用的方式,Java进程可以通过Runtime.exec或ProcessBuilder启动32的代理程序,并传递必要的参数。代理程序负责加载DLL调用相应函数,并将结果输出,Java进程再读取这些输出。这种方式需要确保代理程序是32的,并且能够处理输入参数和输出结果。 然后,编写示例代码。Java部分需要生成进程,发送参数,读取结果。代理程序可以用C++编写,使用32编译器编译,加载DLL,处理参数,调用函数,并输出结果。例如,Java代码调用代理程序,传递参数"add 53",代理解析参数,调用DLL中的add函数,返回结果8,Java读取这个结果。 但是,这种方法可能有性能问题,因为每次调用都需要启动新的进程,对于高频调用不适用。因此,可能需要更高效的IPC机制,比如Socket或命名管道,保持代理程序长时间运行,Java进程通过Socket发送请求,代理处理并返回结果。这样可以减少进程启动的开销。此外,还需要考虑错误处理,比如DLL加载失败、函数调用异常等情况,代理程序需要能够捕获这些错误,并将错误信息返回给Java进程。同时,数据序列化的方式也需要考虑,比如使用JSON或简单的文本格式来传递参数和结果。总结一下,解决方案的关键点在于使用一个32的中间程序作为桥梁,负责加载和调用32DLL,然后通过某种通信机制与64的Java进程交互。这种方法虽然增加了一定的复杂性,但能够有效解决架构不匹配的问题。</think>可以通过创建32代理进程实现跨架构调用,以下是完整解决方案: 1. 创建32C++代理程序(需用32编译器编译): ```cpp #include <windows.h> #include <iostream> #include <string> typedef int(__stdcall* MyFunction)(int, int); int main(int argc, char* argv[]) { if (argc < 4) { std::cerr << "Usage: proxy.dll function arg1 arg2"; return 1; } HINSTANCE hDLL = LoadLibrary("your32.dll"); if (!hDLL) { std::cerr << "Error loading DLL: " << GetLastError(); return 2; } MyFunction func = (MyFunction)GetProcAddress(hDLL, argv[1]); if (!func) { std::cerr << "Function not found"; FreeLibrary(hDLL); return 3; } int result = func(atoi(argv[2]), atoi(argv[3])); std::cout << result; FreeLibrary(hDLL); return 0; } ``` 2. Java端调用代码: ```java public class DllProxy { public static int call32BitDll(String function, int a, int b) throws Exception { Process process = new ProcessBuilder( "path/to/32bit/proxy.exe", function, String.valueOf(a), String.valueOf(b) ).redirectErrorStream(true).start(); BufferedReader reader = new BufferedReader( new InputStreamReader(process.getInputStream())); String line = reader.readLine(); process.waitFor(); if (process.exitValue() != 0) { throw new RuntimeException("Proxy error: " + line); } return Integer.parseInt(line); } public static void main(String[] args) throws Exception { int result = call32BitDll("add", 5, 3); System.out.println("Result: " + result); // 输出8 } } ``` 实现原理: 1. 使用单独的32进程作为桥梁,通过进程间通信传递参数 2. Java通过ProcessBuilder启动代理进程 3. 代理程序加载32DLL并执行实际调用 4. 通过标准输入输出流传递参数和结果 优化建议: 1. 使用命名管道或Socket实现长连接(提高性能) 2. 添加JSON序列化支持复杂参数 3. 实现异步调用机制
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值