32位和64位可以一起工作吗?
Posted
技术标签:
【中文标题】32位和64位可以一起工作吗?【英文标题】:Can 32 bit and 64 bit work together? 【发布时间】:2013-04-05 00:12:21 【问题描述】:64 位库可以在 32 位应用程序中工作吗?例如,我的应用程序 GUI 使用 32 位 Qt。而我的业务核心是一个 64 位的库。操作系统是 64 位的。他们可以一起工作吗?如何工作?谢谢。
【问题讨论】:
您的内核是 32/64 位内核。您的内核不是库。 为什么大家会立即想到 Linux 和 OS 内核? "kernel" 他可能是指他自己的库,它是他应用程序中的一种核心(是的,这确实是一种不正确的称呼方式,但有些人会这样做)。总而言之,他有一个只包含 GUI 的 32 位应用程序和一个带有一些逻辑的单独的 64 位库。 看...我是对的,他只是误用了这个词...:)
@Haroogan 谢谢。我们在非计算机科学界不严格地使用“内核”。
那么,在这种情况下,“内核”到底是什么意思?您的应用程序正在使用的库、操作系统内核还是其他东西?
【参考方案1】:
简而言之:您无法将 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 位进程。
【讨论】:
在 Amiga 系统上执行了一些混合二进制代码,可以运行包含 68k 和 PPC 代码的胖二进制文件。当执行从一个 CPU 运行到另一个 CPU 时,存根被链接以执行上下文切换。但是,如果我没记错的话,它们都以 32b 模式运行。 -1 "总之没有。"是不正确的。 64 位 Windows 上的所有 32 位程序最终都会利用 64 位服务,因为它们是在 64 位操作系统中运行的。为了弥补与 64 位库的差距,您可以使用任意数量的技术,包括 COM。 @Alf:COM 是 RPC。使用 RPC,您可以弥合 32 位和 57 位之间的差距。这并不特别。随着库的发展,64 位 Windows 仍然在 WoW 子系统中附带其库 (DLL) 的 32 位版本,这正是因为您不能在单个进程中混合位。 我已经编辑了我的答案以澄清我在回答什么,似乎这个问题并不完全清楚,我读了一件事,阿尔夫读了另一件事。 原始问题混淆了库和内核。添加 RPC 只会使事情复杂化。都有不同的互操作规则。【参考方案2】:是的,但这很麻烦。
首先,内核不同于库。通常,库在进程的虚拟地址空间中可见;它与您自己的代码共享地址空间。调用库例程只是一个子例程调用。
相反,要向内核请求服务,您的进程会执行一条特殊指令来生成陷阱。这个陷阱会导致处理器做一些特殊的事情,包括将进程的寄存器和其他状态保存在内存中(或在您通常无法访问的特殊处理器寄存器中),更改处理器中的各种模式以使其适合内核,以及更改程序计数器以指向内核的指令。然后内核运行。此时,内核可能在 64 位模式下运行,而您的进程在 32 位模式下运行。但是,内核被设计为意识到这些差异。当您的内核检查您的进程以查看您的请求时,它会查找知道您的进程在 32 位模式下运行的信息和数据结构。内核可以同时支持 32 位和 64 位进程,它只是对每种类型的进程进行不同的处理。
当然,这假定您使用的 64 位内核支持 32 位进程。
通常,当您调用一个库时,您希望它与您的代码具有相同的模式,因为正常的库调用只是一个子程序调用;它不会产生陷阱,也不会改变处理器模式。如果迫切需要从 32 位进程调用 64 位库中的例程,那么您可以创建一个帮助程序 64 位进程。您的 32 位进程将打包一个库调用请求,并通过某种形式的进程间通信将该请求发送到 64 位助手进程。该辅助进程将调用库例程并将结果发回。
这自然会为每个库调用增加大量开销,因此只有在非常需要且没有更好的选择时才需要这样做。
【讨论】:
+1 即使对内核调用方式的描述过于具体(这是典型的,但绝不是唯一的可能性),我仍然支持【参考方案3】:我正在开发一个完全可以做到这一点的应用程序。应用程序核心是 x64(并使用 Qt),但它必须与一些设备通信,为此我只有制造商提供的 32 位库。我实现它的方式是有两个应用程序 64 位用于核心和 GUI,32 位控制设备并使用 QSharedMemory 与主要应用程序通信。两款应用均基于 Qt(对应 64 位和 32 位)。
【讨论】:
【参考方案4】:如果您在 Windows 上运行,那么为 32b 编译的应用程序可以在 Windows 64b 主机系统上运行:看看 64b Windows 中内置的WOW64 子系统。
话虽如此,您不能混合为 32b 编译的代码和为 64b 编译的代码。这意味着为 32b 构建的库不能与 64b 代码链接,反之亦然。 (不同的调用约定、栈帧布局、展开除外……)
【讨论】:
是的,但这不是链接到库,而是将系统调用从 32 位代码调用到 64 位内核的系统调用接口。那是完全不同的事情。 (写在上面添加第二段之前,这解释了我的观点) @MatsPetersson:OP 不需要“链接到库”,不需要以不起作用的方式执行任务 X;相反,OP 要求提供有效的方法 "64 位库可以在 32 位应用程序中工作吗?"是什么意思? @MatsPetersson:不知道,但是,提示提示,如何阅读 OP 的第二句话,他通过提供一个例子来澄清这一点?以上是关于32位和64位可以一起工作吗?的主要内容,如果未能解决你的问题,请参考以下文章
navicat for mysql 64位和32位区别,win7 64位下用32位和64位有区别吗??