64位内存分配

8
我被要求用C++创建一个与Delphi兼容的dll,来进行简单的64位内存管理。
背景是,在Delphi系统中需要分配大量的内存块,这些内存块超出了32位可寻址空间。Delphi开发人员向我解释说,他不能使用Delphi命令来分配内存。他说他可以保存一个64位地址,所以他只想调用我提供的函数来分配内存并返回一个64位指针给他。然后再提供另一个函数来释放内存。
现在,我只有VS 2008可用,所以首先我甚至不确定我能否创建一个与Delphi兼容的dll。
有没有Delphi专家能帮助我一下?也许有一种方法可以实现他的要求,而无需重新发明轮子。其他开发人员在Delphi中可能已经遇到过这个问题。
感谢所有的评论。

他还需要一个函数来读写数据到那些内存块,因为他无法从32位进程中进行操作,而且它不能是一个普通的DLL,因为32位进程无法加载它。基本上,它要求你编写类似于旧时代EMS/XMS内存"扩展器"的东西... - user160694
5个回答

7
只有64位进程可以访问64位内存。64位进程只能加载64位dll,而32位进程只能加载32位dll。Delphi编译器只能生成32位二进制文件。
因此,32位的Delphi exe无法加载您的64位c++ dll。它可以加载32位的c++ dll,但是那个dll将无法访问64位内存空间。你被困在这个解决方案中。
使用正确的编译器选项和Windows开关,Delphi可以无问题地访问3GB的内存。如果32位进程使用物理地址扩展,则可以访问更多的内存。然后需要通过地址窗口扩展将内存页面换入和换出32位内存。

此外,32位进程可以在64位操作系统中使用多达约4GB的内存。 - samir105
这已经不完全准确了。Embarcadero已经发布了64位编译器,你可能需要更新你的答案。 - Kenneth Cochran

6
Delphi指针是32位的。无法访问指向的内存,因此即使您的Delphi开发人员可以“存储”要返回给他的64位值,也是徒劳的。以前我写过:-Codegear / Embarcadero的路线图上有一个64位版本的Delphi计划于“2009年中期”发布。产品质量似乎(最后!)优先于准确地达到交货日期,所以不要抱太大希望...但是,在2010年8月,Embarcadero发布了new roadmap here。这没有给出具体的日期,但提到了一个64位编译器预览,预计在2011年上半年发布。

1
近期消息称,64位编译器将在8月左右发布(http://tech.turbu-rpg.com/351/odd-timing),目前仍处于测试阶段。具体发布内容尚不清楚。 - user160694
1
这一次,看起来 (Delphi x64) 真的要发生了。现在有一个 Delphi x64 的测试版:http://www.embarcadero.com/products/delphi/64-bit - PhiS

5

您可以看一下Free Pascal,它包含一个64位版本,并且大部分使用Delphi语法。


4
为了分配由多个进程共享的内存,您应该使用内存映射文件。可在http://www.delphifaq.com/faq/delphi_windows_API/f348.shtml处获取的代码可用于在32位和64位进程之间通信。以下是步骤:
- 创建一个内存映射文件,可以在磁盘上或内存中创建; - 创建一个互斥体以通知文件更改; - 一端将一些数据写入内存映射文件; - 然后它标记互斥体; - 另一端接收互斥体通知; - 然后从内存映射文件中读取数据。
您需要自行在内存映射文件中创建自定义二进制布局以共享任何数据。通过设计,内存映射文件速度快(这是内核级/x86 CPU功能),并且可以处理大量内存(根据我的实验,32位进程最高可达1GB)。
这种通信方式被http://cc.embarcadero.com/Author/802978用于从32位Delphi程序调用任何64位dll。

今天我不会把“高达1GB”的内存称为“巨大的内存” ;) - user160694
@ldsandon 这只是一个理解的问题。从库的角度来看,让“巨大”的数据保留在64位端可能是有意义的,然后仅使用内存映射文件传输所需的值。每次想要调用库时,将整个数据映射到内存中是没有意义的。MM文件只是用来处理函数“参数”。因此,在这种情况下,1 GB的内存对于参数来说是巨大的。 - Arnaud Bouchez

2
您可能还希望添加一种方法,将64位指针固定在32位内存地址上并解除固定。由于这是Delphi,我相信它是特定于Windows的,因此您可以使用Address Windowing Extensions。这样,您就可以支持在32位地址范围内分配、释放、固定和解除固定内存,并仍然利用64位内存分配空间。假设用户实际上会提交内存以适合32位虚拟地址空间。

如果AWE是他所需的,他将能够直接从Delphi中使用AWE。 AWE允许32位进程超越32位地址空间限制,但它通过映射/取消映射页面到和从32位地址空间来工作,因此有些应用程序可能会发现它有用,而其他应用程序则不会。 - user160694

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