在一个程序中组合32位和64位驱动程序

问题描述 投票:2回答:2

我需要加载.dll文件中提供的不同硬件驱动程序。问题似乎是一个设备的驱动程序是64位dll,另一个设备(相当旧)显然依赖于32位dll中给出的驱动程序。我想通过一个用C#编写的程序来控制它们,这个程序将通过python包装器运行。

显然,我无法直接从一个程序运行这两个设备,但我需要一种方法来相互依赖它们 - 例如:设备1等待设备2完成某项工作。有没有办法绕过这个问题,还是我需要在两个单独的程序中运行它们并通过python包装器相互管理操作?

问候

c# winapi dll x86 64bit
2个回答
4
投票

在64位Windows 64位进程不能使用32位DLL和32位进程不能使用64位DLL。微软有documented这个:

在64位Windows上,64位进程无法加载32位动态链接库(DLL)。此外,32位进程无法加载64位DLL。

您需要一个32位进程与32位DLL和64位进程通信以与64位DLL进行通信。微软说:

但是,64位Windows支持64位和32位进程之间的远程过程调用(RPC)(在同一台计算机上和计算机之间)。

然后问题就变成了如何让Python与这些进程通信。需要某种形式的进程间通信(IPC)。微软几十年前创建了一项技术,可以做到这一点 - 使用Out of Process COM服务器(进程外)的COM接口。

一般的想法是:

  • 创建一个64位的进程外COM服务器,它包装(并公开)64位DLL所需的方法和数据。
  • 创建一个32位的进程外COM服务器,它包装(并公开)32位DLL所需的方法和数据。
  • 写入实例化COM对象并调用其接口的32位或64位客户端代码。 Python可以通过win32com用作COM客户端

COM提供了一种IPC机制,允许64位客户端访问64位进程外COM服务器,并允许64位客户端访问32位进程外服务器。您甚至可以让32位客户端与32位和64位进程外COM服务器进行通信。

我没有使用较新的MS语言完成低级Windows工作。当我不得不在你的问题中做你需要的两个主要技术,使得编写COM服务器和COM接口变得容易:

我有一个用于ATL的preference,因为它不需要MFC库并且开销较少。


2
投票

是的,您将需要2个独立的进程,从不同的可执行文件运行。只有32位可执行文件才能加载32位DLL。 (请参阅@ MichaelPetch的答案,获取有用如何使用远程过程调用机制与另一个进行通信的详细信息,该远程过程调用机制可以模拟从64位代码调用32位函数,反之亦然。)

x86 32位和x86-64是两个独立的体系结构,恰好可以在同一个CPU中以不同的模式执行。他们的机器代码非常相似但不兼容,许多其他的东西也不同,包括目标文件格式,以及指针宽度为8对4字节的ABI细节。


有一个64位进程启动一个线程,使jmp far到32位代码段是技术上可行的(因为GDT有32位和64位代码段条目),但这是疯狂的,并包括DLL的一切支持很差动态加载/符号解析代码。 (还包括内核,所以这甚至都不安全:如果您尝试这样做,中断或系统调用可能会在64位模式下返回32位代码,因为内核知道您的线程/进程是以64位模式启动的。 )

您将无法说服编译器生成32位代码并将其与64位代码链接,即使您在操作系统上使用C也是“安全”的。更高级别的托管语言使其更加无法使用,即使它是手写的asm“安全”。

我提到这一点,以防万一你对实现这一目标在技术上需要什么感到好奇,而不是因为任何人都应该这样做。

但是如果它是安全的,理论上你可以为32位DLL中的每个函数编写(手动asm)包装函数,在调用函数之前更改为32位模式。

显然这是早期的32位Windows;你可以通过操作系统提供的“thunk”包装器从32位代码调用16位DLL。但是对64位代码的32位DLL没有类似的支持,反之亦然。

© www.soinside.com 2019 - 2024. All rights reserved.