将 32 位和 64 位 DLL 合并到一个程序中
我需要加载 .dll 文件中提供的不同硬件驱动程序。 问题似乎是一个设备的驱动程序是在 64 位 dll 中给出的,而另一个设备(相当旧)显然依赖于 32 位 dll 中给出的驱动程序。我想通过一个用 C# 编写的程序来控制它们,该程序将通过 python 包装器运行。
显然,我无法直接从一个程序运行这两个设备,但我需要一种方法来根据彼此对它们进行寻址 - 例如:设备 1 等待设备 2 完成某些工作。有什么方法可以规避这个问题,还是我需要在两个单独的程序中运行它们,并通过 python 包装器管理彼此依赖的操作?
I need to load different hardware drivers that are provided in .dll files.
The problem appears to be that the drivers for one device are given in a 64bit dll, the other device (rather old) apparently relies on drivers given in a 32bit dll. I want to control them through a program written in C# which will be run through a python wrapper.
Obviously I cant run both devices from one program directly but I need a way to address them depending on each other - for example: device 1 waiting for device 2 to finish some job. Is there any way to circumvent this issue or will I need to run them in two separate programs and manage actions depending on each other through the python wrapper?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
在 64 位 Windows 上,64 位进程无法使用 32 位 DLL,32 位进程也无法使用 64 位 DLL。 Microsoft 已记录以下内容:
您需要一个与 32 位 DLL 通信的 32 位进程,以及与 64 位 DLL 通信的 64 位进程。微软是这样说的:
那么问题之一就变成了如何让 Python 与这些进程进行通信。需要某种形式的进程间通信(IPC)。 Microsoft 在几十年前创建了一项可以做到这一点的技术 - 使用进程外 COM 服务器(进程外)的 COM 接口。
总体思路是:
COM 在底层提供了一种 IPC 机制,允许 64 位客户端访问 64 位进程外 COM 服务器,并允许 64 位客户端访问 32 位进程外服务器。您甚至可以让 32 位客户端与 32 位和 64 位进程外 COM 服务器进行通信。
我还没有使用较新的 MS 语言完成低级 Windows 工作。当我必须做你的问题中需要的事情时,可以轻松编写 COM 服务器和 COM 接口的两种主要技术是:
我有一个 优先 ATL,因为它不需要 MFC 库并且开销较小。
On 64-bit Windows 64-bit processes can not use 32-bit DLLs and 32-bit processes can't use 64-bit DLLs. Microsoft has documented this:
You would need a 32-bit process that communicates with the 32-bit DLL and a 64-bit process to communicate with the 64-bit DLL. Microsoft says this:
The problem then becomes one of how to have Python communicate with these processes. Some form of Interprocess Communication (IPC) would be needed. Microsoft created a technology decades ago that can do just that - COM interfaces using Out of Process COM servers (out-of-proc).
The general idea is:
COM provides an IPC mechanism under the hood that allows a 64-bit client to access a 64-bit out-of-proc COM server and for a 64-bit client to access a 32-bit out-of-proc server. You can even have 32-bit clients communicate with 32-bit and 64-bit out-of-proc COM servers as well.
I haven't done low level Windows work using the newer MS languages. When I had to do what you needed in your question the two main technologies that made it easy to write COM servers and COM interfaces were:
I had a preference for ATL since it didn't require the MFC library and had less overhead.
是的,您将需要 2 个独立的进程,从不同的可执行文件运行。只有 32 位可执行文件才能加载 32 位 DLL。 请参阅 @MichaelPetch 的回答,了解有关如何使用远程过程调用机制与另一个进行通信的详细信息,该机制可以模拟从 64 位代码调用 32 位函数,反之亦然。)
( 32 位和 x86-64 是两个独立的体系结构,只是碰巧可以在不同的模式下由同一 CPU 执行。它们的机器代码非常相似但不兼容,并且许多其他方面也有所不同,包括目标文件格式和 ABI 详细信息,例如指针宽度为 8 字节与 4 字节。
让 64 位进程启动一个对 32 位代码段执行
jmp far
的线程在技术上是可行的(因为 GDT 有 32 位和 64 位代码段)条目),但这太疯狂了,而且包括 DLL 动态加载/符号解析代码在内的所有内容都很难支持。 (还包括内核,所以这甚至不安全:如果您尝试这样做,中断或系统调用可能会在 64 位模式下返回 32 位代码,因为内核知道您的线程/进程以 64 位模式启动。)您将无法说服编译器生成 32 位代码并将其与 64 位代码链接,即使您在“安全”的操作系统上使用 C这。更高级的托管语言使其更加无法使用,即使它对于手写汇编是“安全的”。
我提到这一点只是为了让您好奇实现这一目标在技术上需要什么,不是因为任何人都应该这样做。
但如果它是安全的,那么在理论上,您可以为 32 位 DLL 中的每个函数编写(在 asm 中手动)包装函数,在调用该函数之前,该函数会更改为 32 位模式。
显然这是早期 32 位 Windows 的事情;您可以通过操作系统提供的“thunk”包装器从 32 位代码调用 16 位 DLL。 但是对于 64 位代码的 32 位 DLL 没有类似的支持,反之亦然。
Yes you will need 2 separate processes, running from different executables. Only 32-bit executables can load 32-bit DLLs. (See @MichaelPetch's answer for useful suggestions for details of how to get one to communicate with the other with a remote-procedure-call mechanism that can simulate calling 32-bit functions from 64-bit code or vice versa.)
x86 32-bit and x86-64 are two separate architectures that just happen to be both executable by the same CPU, in different modes. Their machine-code is very similar but not compatible, and many other things are different too, including object file format, and ABI details like pointer width being 8 vs. 4 bytes.
Having a 64-bit process start a thread that does a
jmp far
to a 32-bit code segment is technically possible (because the GDT has 32 and 64-bit code segment entries), but that's insane and very poorly supported by everything including the DLL dynamic loading / symbol resolving code. (Also including the kernel, so this is not even safe: an interrupt or system call could return to 32-bit code in 64-bit mode if you tried this, because the kernel knows your thread / process started in 64-bit mode.)You won't be able to convince a compiler to generate 32-bit code and link it with 64-bit code, even if you were using C on an OS where it was "safe" to do this. A higher-level managed language makes it even more unusable even if it was "safe" with hand-written asm.
I mention this just in case you're curious about what it would technically require to make this happen, not because anyone should ever do this.
But if it was safe, in theory you could write (by hand in asm) wrapper functions for every function in the 32-bit DLL that changes to 32-bit mode before calling the function.
Apparently this was a thing early 32-bit Windows; you could call 16-bit DLLs from 32-bit code via a "thunk" wrapper that the OS supplied. But there's no similar support for 32-bit DLLs from 64-bit code or vice versa.