代码之家  ›  专栏  ›  技术社区  ›  user1899020

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

  •  21
  • user1899020  · 技术社区  · 12 年前

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

    4 回复  |  直到 12 年前
        1
  •  23
  •   Mats Petersson    12 年前

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

    您可以在64位操作系统(至少是AMD、Intel和Sparc等所有流行的32/64位处理器)上使用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位的进程。

        2
  •  7
  •   Eric Postpischil    12 年前

    是的,但这是个大麻烦。

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

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

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

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

    当然,这会给每个库调用增加很大的开销,所以只有在非常需要并且没有更好的选择的情况下,才想这样做。

        3
  •  2
  •   Archie    12 年前

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

        4
  •  1
  •   Jens Kirk Roybal    12 年前

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

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

    推荐文章