从64位应用程序加载32位共享库?

16
我有一个编译为32位的共享库。我能否从64位应用程序中使用它,还是需要将共享库也编译为64位?

2
什么操作系统?这很可能很重要。 - Paul Tomblin
1
@Paul:实际上这并不重要。假设是x86-64,处理器在任何给定时刻都处于长模式(64位)、保护模式(32位)或实模式(16位)之一。当线程被调度时,模式被设置为与进程匹配,而进程只能是其中之一。这是x86/x86-64在其核心工作方式的问题。 - Evan Teran
+1 是为了问一个看似显而易见的问题,但这样做确实让问题变得更加明显。 - TheBlastOne
@EvanTeran 操作系统很重要,因为它可以创建一个thunk,以允许64位进程调用32位库,反之亦然。例如,32位Windows允许16位和32位代码相互调用。或者ARM64 Windows有一个thunk来实现ARM64和x86-64代码的互操作性。在64位系统中,这是因为没有现代操作系统编写者选择实现thunk功能。 - phuclv
@phuclv,这个确实很难做到...但是,当然,你可以尝试一下,通过一个调用系统调用的思路来复制参数到低地址,将进程模式切换为32位,然后调用函数,再将任何结果复制回来,最后恢复进程模式并返回。但是模式是针对进程的,所以你要么挂起进程中的其他线程,要么在另一个进程中运行,并使用我在下面回答中提到的IPC。你说得对,从技术上来说是可行的...但是它会有严重的限制。 - Evan Teran
作为后续,如果您将线程实现为独立的进程,它们“碰巧映射到相同的页面”,您可以针对每个线程进行此操作...但是复杂性只会累积。正确实现将是一场噩梦,并且肯定会导致性能相当糟糕,这也是为什么没有操作系统选择实现此类机制的原因。但它可能“能够工作”。 - Evan Teran
2个回答

18

不行,你不能通过常规方式在64位应用程序中加载32位库。

有一些巧妙的技巧,比如使用一个32位应用程序来通过IPC接口加载库并导出函数,但如果你有将库编译为64位的选项,那么这绝对是最好的选择。


你提到的这个巧妙的技巧仍然在32位进程中加载DLL。你知道有没有任何可以在64位进程中加载32位DLL的技巧吗? - John Dibling
1
@John:没有任何可行的方法。当然,你可以在进程中分配内存,并手动将32位dll的二进制代码读入其中。但处理器会将其视为64位指令,这些指令将无法正确运行。在x86-64/x86架构下,这是不可能完成的。 - Evan Teran

8

你不能从64位应用程序中动态或静态加载32位库,反之亦然。

以下是我知道的一些解决方法:

  1. 制作一个64位版本的DLL
  2. 制作一个32位版本的应用程序
  3. 引入一个COM代理对象(也称为代理),作为通信中介。 在此处描述
  4. 将DLL托管在单独的(32位)EXE中,并使用IPC技术

有许多进程间通信(IPC)技术。以下是一些示例:


3
即使在IPC技术列表中缺少共享内存、共享文件、数据库表、RFC、COM和视频屏幕探测等方式,仍需加上“一些IPC技术包括:”的短语。换句话说,建议您在“有许多进程间通信(IPC)技术:”的句子后面添加“其中一些是:”。 - TheBlastOne

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接