Сборки.NET и перебазирование DLL
Согласно этой статье, перекомпоновка не требуется для сборок.NET из-за JIT-компиляции кода. В статье говорится:
"JIT-скомпилированный код не имеет проблемы перебазирования, так как адреса генерируются во время выполнения в зависимости от того, где код помещен в память. Кроме того, MSIL редко страдает от пропадания базового адреса, поскольку ссылки MSIL основаны на токене, а не на адресе Таким образом, когда используется JIT-компилятор, система устойчива к коллизиям базовых адресов. "
Однако я заметил, что VS2008 назначает базовый адрес по умолчанию 0x0400000 для всех сборок (свойства проекта> сборка> расширенный), и если я делаю listdlls /r
для моего процесса все мои сборки.NET фактически перебазируются по умолчанию.
Если я назначаю адреса сам, перебазирование не производится.
Мой вопрос: что перебазируется в этом случае и почему?
РЕДАКТИРОВАТЬ: я должен добавить, что я не говорю о сборках NGen.
2 ответа
Механизм загрузки CLR использует LoadLibrary за кулисами, так что вы наблюдаете: две сборки не могут быть загружены по одному адресу. Теперь, что люди часто имеют в виду, когда пытаются перебить dll - это избежать совершенства. попадание исправлений, например, абсолютные адреса и вызовы функций должны быть "перемещены" с загруженным базовым адресом. CLR не имеет этой проблемы (не уверен насчет статических данных в приложении, что является второй частью этих исправлений, мне нужно прочитать об этом), потому что код MSIL загружается по требованию при вызове функции в управляемом коде. Затем MSIL соединяется и помещается в кучу, отличную от обычной кучи объектов, как я полагаю, точно так же, как CLR выделяет и размещает новые объекты в вашем приложении.
На какой ОС вы работаете? Я знаю, что в Vista и за ее пределами появился ASLR, который рандомизирует адресное пространство, в которое он загружается, в dll. Это происходит для системных библиотек, но не уверен насчет.net - может быть, что-то посмотреть.