64位程序如何调用32位dll(简单解决方案 )

因为一些原因,我们写64位程序时需要调用32位的dll,或者32位程序需要调用64位的dll


项目中我也遇到了这么一个没法回避的问题

看网上有写什么进程外com,没去研究,我用了一个比较简单的方案可以实现

主要就两个方案的结合

1.WM_COPYDATA

2.共享内存


当a程序SendMessage发送WM_COPYDATA 时,b程序执行WM_COPYDATA处理函数,此时a程序阻塞在SendMessage处,只有b程序执行处理函数结束后,a程序才继续执行SendMessage后的语句。这样就可以实现在A程序需要调用dll函数时,通过发送WM_COPYDATA消息,让b程序去调用需要的dll,然后将结果返回到a程序。


WM_COPYDATA消息是传输少量只读数据给其他程序的,所以可以把调用dll所需的参数值传递给b程序。b程序调用dll后如果将结果给a程序呢?这里就可以用共享内存。

b程序开一个共享内存,将结果写入共享内存,当a程序等到b程序 执行完WM_COPYDATA后,通过共享内存就拿到dll函数执行结果。


a程序可以在启动时打开b程序,退出时关闭b程序。b程序在启动时就开一个共享内存(当然,如果dll函数执行结果长度实在没办法用一个足够的缓冲区定义大小,也可以每次执行dll函数时开一个共享内存),并且b程序ShowWindow(SW_HIDE)隐藏掉。




实际的代码流程假设这样

struct PT
{
PT() :x(-1), y(-1) {}
int x;
int y;
};    存储dll函数返回结果的结构体

=======================

一段代码 。。。。

int    param = 10;


PT  pt;

fun(param,   &pt.x,  &pt.y );    这里调用了一个dll中的函数,这个函数进行了很复杂的运算出来个结果


int   y = pt.y* 5...

一段代码。。。。。

=======================





a、b程序公用的定义

#define mapFileName   _T("share")  //共享内存名称
const int ShareSize = sizeof(PT);

#define PrjName      _T("prj")  //b程序窗口名。。由于b程序需要隐藏,在b程序初始化时SetWindowText(PrjName);


PT *m_pt;//b程序程序变量,指向共享内存中数据

=====第一步

b程序启动时开启共享内存

HANDLE hMapFile = CreateFileMapping(INVALID_HANDLE_VALUE, NULL, PAGE_READWRITE, 0, ShareSize, mapFileName);
m_pt = (PT*)MapViewOfFile(hMapFile, FILE_MAP_ALL_ACCESS, 0, 0, ShareSize);//


=====第二步

a程序执行函数时发送WM_COPYDATA消息

int    param = 10;




HWND  hWnd = ::FindWindow(NULL, PrjName); 
if (hWnd == NULL) { return; }
COPYDATASTRUCT cds;
cds.dwData = 0;
cds.lpData = &param;//可以是结构体
cds.cbData = sizeof(param);
SendMessage(hWnd, (UINT)WM_COPYDATA, (WPARAM)m_hWnd, (LPARAM)&cds);


======第三步

b程序处理WM_COPYDATA消息


BOOL C**Dlg::OnCopyData(CWnd* pWnd, COPYDATASTRUCT* pCopyDataStruct)

{

       int param = (int)pCopyDataStruct->lpData;


       fun(param,   &m_pt->x,& m_pt->y); //dll中的函数,m_pt已经是共享内存指针,直接进行操作写入共享内存

     

       return CDialog::OnCopyData(pWnd,pCopyDataStruct);

}


======第四步

a程序从共享内存拿到结果

紧跟着SendMessage(hWnd, (UINT)WM_COPYDATA, (WPARAM)m_hWnd, (LPARAM)&cds);这句之后



HANDLE hMapFile = OpenFileMapping(FILE_MAP_ALL_ACCESS, FALSE, mapFileName);
if (hMapFile == NULL)    return NULL;

PT *ptr = (PT*)MapViewOfFile(hMapFile, FILE_MAP_ALL_ACCESS, 0, 0, ShareSize);
CloseHandle(hMapFile);/// 一定要关句柄。。。。


int   y = ptr->y* 5...    对结果进行使用




经过这个流程下来就实现了调用与程序位数不同的dll

当然这个是单线程的,多线程就得开不同共享内存



  • 3
    点赞
  • 38
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: 要在64位JDK环境下调用32位DLL文件,您需要执行以下步骤: 1. 确定您的操作系统是否为64位,如果是,请下载并安装32位Java运行时环境(JRE)。 2. 在32位Java JRE中编写代码,以便它可以调用32位DLL文件。请注意,由于32位DLL文件不受64位Java JRE支持,因此必须使用32位Java JRE。 3. 将32位DLL文件复制到您的计算机上,并确保它们位于Java可以找到的位置。可以将其复制到Java库路径或系统路径中。 4. 将32位DLL文件与Java代码连接起来。您可以使用Java Native Interface(JNI)来实现这一点。 JNI允许Java代码调用本地库(如DLL文件),并且可以在32位Java JRE和64位Java JRE中使用。 5. 在Java代码中使用System.loadLibrary()函数来加载32位DLL文件。 6. 测试您的代码并确保它可以正确调用32位DLL文件。 ### 回答2: 在64位JDK环境中调用32位DLL文件的问题可以通过以下步骤解决: 1. 确认操作系统:首先需要确保操作系统是64位版本的。如果操作系统是32位的,那么无论使用哪个版本的JDK,都只能调用32位DLL文件。 2. 安装32位JDK:在64位JDK环境中调用32位DLL文件,需要安装32位的JDK。因为32位DLL文件是由32位JDK生成的,所以只有相同位数的JDK能够正确地加载并调用DLL文件。 3. 配置环境变量:将32位JDK的安装路径添加到系统的环境变量中。这样,可以确保在命令行或其他开发工具中使用32位JDK进行编译和运行程序。 4. 设置Java库路径:在Java代码中,使用System.setProperty("java.library.path", "DLL文件路径")指定DLL文件的路径。这样,JVM会在指定的路径中找到并加载32位DLL文件。 5. 使用32位JRE:如果使用的是JRE而不是JDK,同样需要安装32位的JRE,并在环境变量中配置正确的JRE路径。 需要注意的是,64位JDK环境中调用32位DLL文件可能会导致兼容性问题。因此,建议尽可能使用相同位数的JDK和DLL文件。如果DLL文件是由第三方提供的,可以尝试联系DLL文件的提供方,获取64位版本的DLL文件。 总结起来,解决64位JDK环境中调用32位DLL文件的问题,需要确认操作系统位数,安装相同位数的JDK或JRE,并配置正确的环境变量和Java库路径。 ### 回答3: 要在64位JDK环境中调用32位DLL文件,我们需要采取以下解决方法: 1. 选择32位JDK环境:如果可能的话,可以考虑安装32位JDK环境,因为32位JDK环境能兼容32位DLL文件。这样就可以直接使用32位JDK环境调用32位DLL文件,无需做其他处理。 2. 使用Java Native Interface(JNI):JNI是Java提供的一种机制,允许Java代码调用本地语言的函数。通过编写桥接函数,将Java代码与DLL文件连接起来。在编写JNI函数时,需要根据DLL文件的调用规范(例如C调用规范)进行适当的声明和封装。 3. 使用Java Native Access(JNA)库:JNA是一个开源库,可以简化Java调用本地函数的过程。通过使用JNA库,在Java代码中声明和定义DLL文件的函数和数据结构,使得可以直接调用32位DLL文件中的函数。在JNA中,没有必要编写JNI函数,而是通过直接调用DLL文件的函数来实现功能。 4. 通过进程间通信(IPC):如果以上方法都无法解决问题,可以考虑通过IPC与一个32位进程进行通信。在32位进程中加载32位DLL文件,并提供接口让64位JDK环境中的Java代码调用。可以使用进程间通信机制,如共享内存或管道,实现Java代码与32位进程之间的数据交换和通信。 以上是解决64位JDK环境中调用32位DLL文件的一些方法。根据具体情况选择适合的解决方案,并根据需求进行详细实施和测试。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值