Загрузка библиотеки из смещения в файл

#windows #dll #loadlibrary

#Windows #dll #загрузка библиотеки

Вопрос:

Я пишу игровой движок с возможностью написания сценариев, для которого у меня есть большое количество классов, выполняющих различные задачи. Размер движка быстро растет, и поэтому я подумал о разделении большого исполняемого файла на DLL-модули, чтобы в него могли быть включены только те компоненты, которые действительно использует разработчик игры. Когда пользователь компилирует свою игру (то есть свой скрипт), я хочу, чтобы правильные библиотеки DLL были частью конечного исполняемого файла. У меня уже есть довольно много данных оверлея, поэтому я подумал, что смогу сохранить DLL как часть этого блока. Мой вопрос сводится к следующему:

Возможно ли обмануть LoadLibrary, чтобы начать чтение файла с определенным смещением? Это избавило бы меня от необходимости либо извлекать DLL во временный файл, который не является чистым, либо, альтернативно, полностью отменить автоматическое включение DLL и просто дать указание моим пользователям упаковывать DLL вместе со своими играми.

Изначально я думал о том, чтобы использовать подход «загрузить dll из памяти», но отклонил его по соображениям переносимости и просто потому, что это кажется таким ужасным взломом.

Есть мысли?

С уважением,

Филип Беннефалл

Комментарии:

1. Вы, кажется, описываете очень запутанное переосмысление статического связывания. В этом и заключается суть статического связывания — включение необходимых частей библиотечного кода в исполняемый файл.

2. Ну, это в значительной степени то, что я хочу сделать, но это должно быть сделано на основе содержимого скрипта. Таким образом, я не могу выполнить предварительную компиляцию, поскольку это привело бы меня туда, где я нахожусь в настоящее время. Когда пользователь «компилирует» свою игру, происходит не фактическая компиляция C ; это просто движок скрипта, который компилирует свой собственный байтовый код довольно высокого уровня. Затем этот байт-код шифруется и добавляется к копии исполняемого файла движка, который проверяет, есть ли у него соответствующие данные оверлея, добавленные к нему, когда он начинает выполняться.

3. Похоже, вам нужен инструмент, чтобы выяснить, какие части движка используются, а какие нет, а затем повторно связать исполняемый файл движка соответствующим образом, либо используя настоящий компоновщик, либо ваш собственный инструмент для переработки файла.

4. Можете ли вы порекомендовать какие-либо подобные инструменты?

5. Извините, это не то, что мне нужно было исследовать для платформы Windows в последнее время. Вероятно, ваше первое решение будет заключаться в том, чтобы попросить разработчика повторно связать движок или придумать что-нибудь, чтобы удалить ненужные части из уже связанного исполняемого файла, который вы предоставляете.

Ответ №1:

Вы пытаетесь решить проблему, которой не существует. Загрузка библиотеки DLL на самом деле не требует никакой физической памяти. Windows создает файл с отображением в памяти для содержимого DLL. Код из библиотеки DLL загружается только тогда, когда ваша программа вызывает этот код. Неиспользуемый код не требует никаких системных ресурсов, кроме зарезервированных страниц памяти. В 32-разрядной операционной системе этот объем равен 2 миллиардам байт. Вам придется написать много кода, чтобы использовать их все, 50 мегабайт машинного кода — это уже очень большая программа.

Сопоставление памяти также является причиной, по которой вы не можете заставить LoadLibrary () делать то, что вы хотите. Не существует реалистичного сценария, в котором вам нужно.

Изучите параметр компоновщика / DELAYLOAD для повышения производительности при запуске.

Ответ №2:

Я думаю, что каждое решение для этой задачи — «ужасный взлом» и ничего более.

Самый простой способ, который я вижу, — это создать свой собственный виртуальный диск, который представляет пользовательскую файловую систему и взламывает путь доступа к системе из одного реального файла (компиляции ваших библиотек) в несколько отдельных DLL-ов. Например, как это делает TrueCrypt (это с открытым исходным кодом). И затем вы можете использовать LoadLibrary функцию без изменений.

Но единственный правильный способ, который я вижу, это изменить вашу задачу и не использовать этот подход. Я думаю, вам нужно создать свой собственный интерпретатор сценариев и компилятор, используя структуры, указатели и так далее.

Главное, что я не понимаю вашей выгоды от использования библиотек. Я думаю, что любой скомпилированный код в текущее время не весит так много и может быть упакован очень хорошо. Любые другие ресурсы могут загружаться динамически при первом вызове. Все, что вам нужно сделать, это правильно организовать рабочие циклы всех компонентов скриптового движка.