32位和64位可以一起工作吗?

时间:2013-04-12 12:47:37

标签: c++ 64-bit 32-bit

64位库可以在32位应用程序中工作吗?例如,我的应用程序GUI使用32位Qt。我的业务核心是64位库。操作系统是64位。他们可以一起工作吗?感谢。

4 个答案:

答案 0 :(得分:19)

简而言之:您无法将32位应用程序链接到64位库。

您可以在64位操作系统(至少所有流行的32位/ 64位处理器,如AMD,Intel和Sparc)上使用32位共享库来运行32位应用程序。但这并不涉及任何图书馆。

更长的答案:我参与了一些为x86设计64位Linux内核的团队(在郊外)。简要地(与整个项目相比,讨论持续了几个小时)进行了一些讨论,讨论如何从技术上进行这项工作。对此的简短总结是,在64位中存在32位不可用的寄存器。还存在存储器地址和寄存器中额外32位的问题。所有这些都可以解决,假设库本身“知道”它是一个32位兼容的库。但是我们基本上有一个64位的库被写成32位库,我们有点失去了意义。

“更多寄存器”可能不适用于某些处理器,但更大的寄存器地址/位范围绝对适用于所有32位和64位兼容处理器。我不知道任何单个处理器允许32位代码调用64位共享库或静态库。它只是不起作用,除非专门编写代码来应对,这违背了使用通用64位库来支持32位应用程序的目的。

编辑:

以上讨论了链接一个可执行单元,例如,可执行文件,共享库或静态库。这必须是所有“一点点”,32或64 - 没有混合。

当一个进程与另一个进程对话时(例如一个GUI应用程序显示来自非GUI进程的状态),只要这两个进程使用相同的协议[通常,IPC不允许传递指针无论如何,所以32- / 64位转换不是一个大问题],你可以有一个32位的进程和另一个64位的进程。

答案 1 :(得分:6)

是的,但这是一个很大的麻烦。

首先,内核与库不同。通常,库在您的进程的虚拟地址空间中可见;它与您自己的代码共享地址空间。调用库例程只是一个子例程调用。

相反,要从内核请求服务,您的进程会执行特殊指令来生成陷阱。此陷阱导致处理器执行一些特殊操作,包括将进程的寄存器和其他状态保存在内存中(或者在通常无法访问的特殊处理器寄存器中),更改处理器中的各种模式以使其适合内核,以及更改程序计数器以指向内核的指令。然后内核正在运行。此时,内核可能在64位模式下运行,而您的进程在32位模式下运行。但是,内核旨在了解这些差异。当您的内核检查您的进程以查看您的请求时,它会查找信息和数据结构,知道您的进程是以32位模式运行的。内核可以支持32位和64位进程,它只是以不同的方式处理每种类型的进程。

当然,这假设您使用的64位内核支持32位进程。

通常,当你调用一个库时,你希望它与你的代码模式相同,因为普通的库调用只是一个子程序调用;它不会生成陷阱,也不会更改处理器模式。如果迫切需要从32位进程调用64位库中的例程,那么您可以创建一个帮助程序64位进程。您的32位进程将打包一个库调用请求,并通过某种形式的进程间通信将该请求发送到64位帮助程序进程。该辅助进程将调用库例程并将结果发回。

当然,这会给每个库调用带来很大的开销,所以只有在需求很大而且没有更好的选择时,才能做到这一点。

答案 2 :(得分:2)

我正在开发一个正是这样的应用程序。应用程序核心是x64(并使用Qt),但它必须与某些设备通信,我只有来自制造商的32位库。我实现它的方式是为核心和GUI提供两个64位应用程序,使用QSharedMemory控制设备并与主应用程序通信的32位。这两个应用程序都基于Qt(相应地为64和32位)。

答案 3 :(得分:1)

如果您在Windows上运行,那么针对32b编译的应用程序可以在Windows 64b主机系统上运行:请查看内置于64b Windows的WOW64子系统。

话虽如此,你可以将为32b编译的代码与为64b编译的代码混合。这意味着为32b构建的库无法与64b代码链接,反之亦然。 (不同的调用约定,堆栈框架布局,除了展开,......)