使用p / invoke与具有大量静态数据分配的Fortran库进行交互的.Net应用程序在Windows远低于2 GB静态数据限制时无法加载库。我通过p / invoke加载成功的最大静态代码大小约为1 GB。如果我编写一个加载库的简单C程序,我可以加载最大1.9 GB的静态数据。两个测试应用程序都是32位。
托管应用程序尝试通过LoadLibrary加载库失败,并且Marshal.GetLastWin32Error返回的错误消息是“没有足够的存储空间可用于处理此命令”。 CLR处理非托管库的静态内存分配方式与C ++运行时提供的二进制可执行文件的方式有区别吗?
答案 0 :(得分:6)
你在C程序中也没有太多的保证,它只需要在基地址加载一个蹩脚注入的DLL,将可用的地址空间分成两部分,操作系统再也找不到足够大的空洞了适合那个巨大的部分。
在.NET程序中更糟糕的是,当你的pinvoke调用开始运行时,它已经加载了大量的代码和数据。例如至少10堆。最大的漏洞一般是650-750兆字节,但只能在启动后立即进行。 SysInternals的VMMap实用程序可以显示土地的位置。
你可以做的很少,以使洞更大。确保您的.NET版本足够新,以便在64位版本的Windows上获得4 GB的地址空间。您的Fortran DLL需要/ LARGEADDRESSAWARE才能工作。重构Fortran代码,以便它从堆中分配,这肯定是你不想做的事情。很高兴开始构建它的64位版本,这很简单。