#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
функцию без изменений.
Но единственный правильный способ, который я вижу, это изменить вашу задачу и не использовать этот подход. Я думаю, вам нужно создать свой собственный интерпретатор сценариев и компилятор, используя структуры, указатели и так далее.
Главное, что я не понимаю вашей выгоды от использования библиотек. Я думаю, что любой скомпилированный код в текущее время не весит так много и может быть упакован очень хорошо. Любые другие ресурсы могут загружаться динамически при первом вызове. Все, что вам нужно сделать, это правильно организовать рабочие циклы всех компонентов скриптового движка.