我正在尝试基于运行在 .net4 上的小型测试解决方案重新构建 Dll,该解决方案由一个小型 .exe 和三个小型 .Dll 组成。程序集引用已正确设置,程序可以正常编译和运行。
这个练习的目的是检查变基是如何工作的,以便我可以将它与 ngen 联系起来,并在我正在从事的大型项目中提高性能。
我尝试了许多不同的方法来重新定位 Dll,并使用 vmmap、Visual Studio 模块调试器窗口和进程资源管理器监控结果;到目前为止还没有成功:
我已将Dll1.dll、Dll2.dll 和 Dll3.dll 的 Build- >Advanced->DLL Base Address设置分别设置为 0x41000000、0x42000000 和 0x43000000。这些地址肯定被保存为每个 Dll 中的首选基地址,但对于每次运行,Dll 都会不规则地将其图像重新定位到内存中的许多不同位置。
我试过使用这个应用程序。它生成的日志显示 Dll 确实具有内置的首选基地址(由我选择),但是在运行时结果仍然不稳定
我试过使用ngen。这导致 .ni 版本的 Dll 与原始 Dll 一起加载,并且所有 6 个版本的内存位置都与我要求的位置相去甚远。
我已经尝试将我的图像粘贴在 GAC 中。令人振奋的是,只有 GAC 版本的 Dll 被加载,但它们的内存位置仍然不稳定。
我已经尝试过上述每种组合的感觉。没有成功。
在运行时使用 VMMap 进行检查表明,在 0x10000000 和 0x50000000 之间的地址空间中存在巨大的可用内存差距,因此应该没有冲突,也不需要发生 Dll 变基。Dll 也非常小,我在它们之间留下的 0x01000000 间隙非常大,所以它们不应该相互碰撞。
我错过了什么?
在此练习中,我的主要参考资料是这篇文章,该文章信息量很大,但它是在 2006 年为 .Net2 编写的:从那时到现在,有什么根本性的变化吗?
我严重怀疑它是否有很大的不同,但这是我正在使用的代码以防万一:
程序.cs:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using Dll1;
using Dll2;
using Dll3;
namespace ConsoleApplication1
{
class Program
{
static void Main(string[] args)
{
Thread.CurrentThread.Name = "Poodle";
Console.ReadLine();
//Thread.Sleep(10000);
Blah();
}
static void Blah()
{
Console.WriteLine(Class2.shrooms(5, 'h'));
Class3.teenAngst();
Class1.Wait();
}
}
}
Class1.cs:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace Dll1
{
public static class Class1
{
public static void Wait()
{
Console.ReadLine();
Console.Write(" ");
}
}
}
Class2.cs:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace Dll2
{
public static class Class2
{
public static string shrooms(int argc, char argv)
{
return "Ranchdaddyx ";
}
}
}
Class3.cs:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace Dll3
{
public static class Class3
{
public static void teenAngst()
{
Console.Write("Belonging ");
}
}
}