Есть ли способ имитировать LD_LIBRARY_PATH в Windows? - PullRequest
6 голосов
/ 25 января 2012

У меня есть программа, делающая графику.Когда я запускаю его в интерактивном режиме, я хочу, чтобы он использовал OpenGL из системы для обеспечения графики с аппаратным ускорением.Когда я запускаю его в пакетном режиме, я хочу иметь возможность перенаправить его для использования библиотеки Mesa GL, чтобы я мог использовать функциональные возможности OSMesa для рендеринга в внеэкранный буфер.Функциональность OSMesa включается с помощью LoadLibrary / GetProcAddress, если выбран вариант пакетного запуска.

В Linux довольно легко сделать эту работу.Используя скрипт-обертку для вызова программы, я могу сделать что-то вроде этого:

if [ "$OPTION" = "batch" ]; then
  export LD_LIBRARY_PATH=$PATHTO/mesalibs:$LD_LIBRARY_PATH
fi

Можно сделать что-то подобное в Windows?

Когда я пытаюсь добавить каталог вПеременная PATH, программа продолжает переходить в систему opengl32.dll.Единственный способ заставить программу использовать совместно используемые библиотеки Mesa GL / OSMesa - это разместить их в том же каталоге, что и моя программа.Однако, когда я это сделаю, программа никогда не будет использовать систему opengl32.dll.

Ответы [ 4 ]

5 голосов
/ 01 февраля 2012

Если я правильно понял, что вы говорите, при запуске процесса загружается неправильная версия opengl32.dll, т. Е. динамическое связывание во время загрузки .Вероятно, нет хорошего способа решить вашу проблему, не меняя это.

Вы говорите, что не можете удобно использовать динамическое связывание во время выполнения (LoadLibrary / GetProcAddress) для opengl32.dll, посколькувызовы поступают из библиотеки Qt.Однако я предполагаю, что библиотека Qt сама по себе динамически связана, поэтому вы должны быть в состоянии решить вашу проблему, используя для этого ссылки во время выполнения.В этом сценарии, при условии, что вы загружаете opengl32.dll перед загрузкой библиотеки Qt, вы должны иметь возможность явно выбрать, какую версию opengl32.dll вы хотите загрузить.

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

1 голос
/ 30 января 2012

Есть несколько способов справиться с этим, в зависимости от библиотек и их имен / местоположений:

Если оба имеют одинаковое имя (opengl32.dll), то вам нужно добавить расположение DLL-библиотеки Mesaк пути поиска, так что он ищется перед системным каталогом.Каталоги заказов проверены в подробностях здесь .Как видите, $PATH идет последним, после системы, поэтому вы не можете просто добавить каталог к ​​этому.Тем не менее, вы можете использовать второй шаг («Текущий каталог»), установив в рабочем каталоге путь, содержащий файлы меза.Обычно это означает запуск приложения с использованием абсолютного пути в каталоге, содержащем файлы.

Это все же не особенно приятно.Если вы можете, вы должны использовать LoadLibrary и проверять переменную среды (OPENGL_LIBRARY_PATH) при запуске приложения.Предполагая, что экспорт из opengl32.dll и DLL-библиотеки Mesa одинаков, вы можете сделать что-то вроде:

void LoadExports()
{
    char location[MAX_PATH];
    getenv("OPENGL_LIBRARY_PATH", location);
    HMODULE oglLib = LoadLibrary(location);

    function1 = GetProcAddress(oglLib, "glVertex2f");
    ...
}

Это будет прекрасно работать, делая почти точно то, что вы хотите.

Однако,если вы хотите сделать это, вы не можете импортировать opengl32.dll, что вы, вероятно, делаете, вам нужно динамически связывать всюду.Убедитесь, что вы не связываетесь с opengl32.lib, и все будет в порядке.В зависимости от того, сколько функций вы используете, настройка может быть затруднена, но код можно легко написать в сценарии, и его нужно выполнить только один раз, вы также можете использовать переменные static для кэширования результатов в течение всего срока жизни программы.Также возможно использовать разные имена функций для разных библиотек, хотя это занимает немного больше логики, поэтому я оставлю вам детали.

0 голосов
/ 01 февраля 2012

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

Однако вы можете использовать Delay Load Imports, чтобы обойти это:

Если вы используете MSVC, вы можете выделить библиотеки DLL, которые вы хотите загрузить самостоятельно, с помощью флага /DELAYIMPORT для компоновщика.

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

После загрузки правильной DLL, пусть ваша вспомогательная функция просто вызовет исходную, которая сама будет выполнять все операции GetProcAddress.

0 голосов
/ 25 января 2012

Хотя это должно быть возможно в окне cmd, похоже, вам не повезло.

Попробуйте: установить переменную в вашем скрипте (RUNNING_IN_SCRIPT = Y) и затем проанализировать эту переменную в вашем исполняемом файлеи LoadLibrary с абсолютного пути установки - обязательно очищайте переменную при выходе.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...