【问题标题】:64bit Memory allocation64位内存分配
【发布时间】:2010-09-07 06:01:47
【问题描述】:

我被要求在 C++ 中创建一个与 Delphi 兼容的 dll 来进行简单的 64 位内存管理。

背景是 Delphi 中的系统需要分配大量内存块,这些内存块可以很好地超出 32 位可寻址空间。 Delphi 开发人员向我解释说,他无法使用可用的 Delphi 命令分配内存。他说他可以持有一个64位的地址,所以他只想调用我提供的一个函数来分配内存并返回一个64位的指针给他。然后另一个函数稍后释放内存。

现在,我只有 VS 2008 可供我使用,所以首先我什至不确定我是否可以首先创建一个与 Delphi 兼容的 dll。

任何 Delphi 专家都愿意帮助我。也许有一种方法可以在不重新发明轮子的情况下实现他的要求。其他开发人员一定在 Delphi 中遇到过这种情况。

感谢所有 cmets。

【问题讨论】:

  • 他还需要函数来读取/写入数据到该内存块,因为他无法从 32 位进程执行此操作,并且它不能是普通 DLL,因为 32 位进程将无法加载它。基本上,它要求你写一些非常类似于旧时代的 EMS/XMS 内存“扩展器”的东西......

标签: c++ delphi memory 64-bit


【解决方案1】:

只有 64 位进程可以寻址 64 位内存。 64 位进程只能加载 64 位 dll,32 位进程只能加载 32 位 dll。 Delphi 的编译器只能生成 32 位二进制文​​件。

所以 32 位 Delphi exe 无法加载您的 64 位 c++ dll。它可以加载 32 位 c++ dll,但该 dll 将无法寻址 64 位内存空间。你有点被这个解决方案卡住了。

使用正确的编译器选项和 Windows 开关,Delphi 可以毫无问题地处理 3GB 内存。如果使用Physical Address Extension,32 位进程可以访问更多内存。然后它需要通过使用Address Windowing Extensions 将内存页面进出32 位内存。

【讨论】:

  • 此外,32 位进程在 64 位操作系统中最多可以使用 ~4GB。
  • 这不再完全准确。由于 Embarcadero 发布了 64 位编译器,您可能想更新您的答案。
【解决方案2】:

Delphi 指针是 32 位的。时期。您的 Delphi 开发人员可能能够“存储”您想要返回给他的 64 位值,但他无法访问它们指向的内存,所以这是徒劳的。

以前,我写过:-

64 位版本的 Delphi 已启用 Codegear/Embarcadero's road map 对于“2009 年年中”。产品质量 似乎(终于!)服用 优先于发货日期 没错,所以不要屏住呼吸......

但是,在 2010 年 8 月,Embarcadero 发布了new roadmap here。这没有给出具体日期,但提到了 64 位编译器预览预计可用性,2011 年上半年

【讨论】:

【解决方案3】:

您可能还想添加一种方法来将 64 位指针固定和取消固定到 32 位内存地址。由于这是 Delphi,我很确定它是特定于 Windows 的,所以您不妨使用Address Windowing Extensions。这样,您可以支持将内存分配、释放以及固定和取消固定到 32 位地址范围,并且仍然可以利用 64 位内存分配空间。假设用户将实际提交内存以使其适合 32 位虚拟地址空间。

【讨论】:

  • 如果他需要 AWE,他可以直接从 Delphi 使用 AWE。 AWE 允许 32 位进程超越 32 位地址空间的限制,但是它可以在 32 位地址空间之间映射/取消映射页面,因此某些应用程序可能会发现它有用,而其他应用程序则没有。
【解决方案4】:

您可以查看Free Pascal,因为它包含 64 位版本,并且大部分是与 Delphi 兼容的语法。

【讨论】:

    【解决方案5】:

    为了分配多个进程共享的内存,你应该使用内存映射文件。

    http://www.delphifaq.com/faq/delphi_windows_API/f348.shtml 提供的代码可用于在 32 位和 64 位进程之间进行通信。

    步骤如下:

    • 在磁盘或内存上创建内存映射文件;
    • 创建互斥锁以通知文件更改;
    • 一端向内存映射文件写入一些数据;
    • 然后它标记互斥体;
    • 另一端收到互斥通知;
    • 然后它从内存映射文件中读取数据。

    您可以在内存映射文件中创建自定义二进制布局,以便共享任何数据。

    根据设计,内存映射文件速度很快(这是内核级/x86 CPU 功能),并且可以处理巨大的内存(根据我的实验,32 位进程最多 1 GB)。

    http://cc.embarcadero.com/Author/802978 使用这种通信方式从 32 位 Delphi 程序调用任何 64 位 dll。

    【讨论】:

    • 今天我不会称“高达 1GB”为“巨大的内存”;)
    • @ldsandon 这是一个理解问题。从库 POV 来看,让“巨大”数据保留在 64 位端是有意义的,然后仅将内存映射文件用于所需值的数据传输。每次要调用库时都映射整个数据是没有意义的。 MM 文件只是在这里处理函数“参数”。所以在这种情况下,1 GB 的内存对于参数来说是巨大的。
    猜你喜欢
    • 2017-04-30
    • 2013-12-23
    • 1970-01-01
    • 2015-12-07
    • 2021-04-10
    • 2011-05-27
    • 1970-01-01
    • 2019-07-19
    • 2019-08-16
    相关资源
    最近更新 更多