Est-il possible de simuler LD_LIBRARY_PATH dans Windows?
J'ai un programme de faire quelques graphiques. Lorsque je l'exécute de manière interactive, je le veux utiliser OpenGL à partir du système à fournir de l'accélération graphique matérielle. Quand je le lance dans le lot, je veux être en mesure de le rediriger vers l'utilisation de la Mesa GL bibliothèque afin que je puisse utiliser OSMesa de la fonctionnalité de rendu d'un écran tampon. Le OSMesa fonctionnalité est activée par faire un LoadLibrary/GetProcAddress si le lot start up option est sélectionnée.
Sur Linux, son assez facile de faire ce travail. À l'aide d'un script pour appeler le programme, je peux faire quelque chose comme ceci:
if [ "$OPTION" = "batch" ]; then
export LD_LIBRARY_PATH=$PATHTO/mesalibs:$LD_LIBRARY_PATH
fi
Il est possible de faire quelque chose de cela dans Windows?
Lorsque j'essaie d'ajouter un répertoire à la variable de CHEMIN d'accès, le programme continue d'aller pour le système opengl32.dll. La seule façon que je peux obtenir le programme à utiliser la Mesa GL/OSMesa bibliothèques partagées est pour les avoir à résider dans le même répertoire que mon programme. Cependant, lorsque je fais cela, le programme ne jamais utiliser le système opengl32.dll.
OriginalL'auteur likso | 2012-01-25
Vous devez vous connecter pour publier un commentaire.
Si j'ai bien compris ce que vous dites correctement, la mauvaise version de opengl32.dll est en cours de chargement lors de votre démarrage du processus, c'est à dire, les temps de charge de liaison dynamique. Il n'y a probablement pas de bonne façon de résoudre votre problème sans changer cela.
Vous dites que vous ne pouvez pas utiliser facilement utiliser le temps d'exécution de la liaison dynamique (LoadLibrary/GetProcAddress) pour opengl32.dll parce que les appels sont à venir à partir de la bibliothèque Qt. Je présume que la bibliothèque Qt est elle-même liée de façon dynamique, cependant, de sorte que vous devriez être en mesure de résoudre votre problème à l'aide d'exécution de liaison. Dans ce scénario, à condition de charge opengl32.dll avant de charger la bibliothèque Qt, vous devriez être en mesure de choisir explicitement la version de opengl32.dll vous souhaitez charger.
Vous pouvez envisager d'utiliser retard de chargement afin de simplifier le processus de déplacement de la charge à l'exécution de la liaison. Dans ce scénario, le premier appel de la bibliothèque Qt causes qu'il soit chargé automatiquement, et vous aurez juste besoin de charger explicitement opengl32.dll d'abord.
OriginalL'auteur Harry Johnston
Il existe quelques façons que vous pouvez soulever, selon le type de bibliothèques et de leurs noms/lieux:
Si les deux ont le même nom (opengl32.dll), alors vous devez ajouter la Mesa DLL emplacement dans le chemin de recherche tel qu'il est recherché avant le répertoire système. L'ordre des répertoires archivés est détaillée ici. Comme vous pouvez le voir,
$PATH
est le dernier, après que le système, de sorte que vous ne pouvez pas simplement ajouter le répertoire. Cependant, vous pouvez faire usage de la deuxième étape ("Le répertoire courant") en définissant le répertoire de travail d'un chemin d'accès contenant la mesa de fichiers. Généralement, cela signifie en commençant l'application à l'aide d'un chemin d'accès absolu tandis que dans le répertoire contenant les fichiers.C'est encore pas particulièrement agréable. Si vous le pouvez, vous devez utiliser
LoadLibrary
et vérifier la présence d'une variable d'environnement (OPENGL_LIBRARY_PATH
) lorsque l'application démarre. En supposant que les exportations deopengl32.dll
et Mesa de DLL sont les mêmes, vous pouvez faire quelque chose comme:Cela fonctionne parfaitement bien, en faisant presque exactement ce que vous voulez.
Toutefois, si vous voulez le faire, vous ne pouvez pas importer des
opengl32.dll
, vous êtes probablement en train de faire, vous devez lier dynamiquement tout au long de. Assurez-vous de ne pas lier contreopengl32.lib
et vous devriez être bien. En fonction du nombre de fonctions que vous utilisez, il peut être une douleur à mettre en place, mais le code peut facilement être scripté et de ne la faire qu'une fois, vous pouvez également utiliserstatic
variables pour mettre en cache les résultats pour la durée de vie du programme. Il est également possible d'utiliser différents noms de fonction pour différentes bibliothèques, bien que cela prend un peu plus de logique, je vais donc laisser les détails à vous.Il y a un truc que vous pouvez utiliser, si vous êtes sûr que votre bibliothèque de charge avant de Qt (ou vous pouvez faire un stub qui va le faire): appel
LoadLibrary
sur la bibliothèque souhaitée à partir de là, de sorte qu'un module chargé avec le nom existe lorsque la bibliothèque Qt de charges. L'éditeur de liens se vérifier pouropengl32.dll
, et si l'on est déjà chargé, utilisez que. Sinon, vous aurez à travailler avec l'ordre de chargement, et peut-être vérifier dans une dépendance de processus/outil de suivi de ce parcours que c'est de la recherche.Avez-vous plus d'infos sur ce "truc"? J'ai essayé de faire quelque chose comme cela dans un programme de test simple (comme déjà suggéré par KevinDTimm), où j'ai fait la fonction LoadLibrary sur la Mesa opengl32.dll et osmesa32.dll et puis les appels à OSMesaCreateContext, OSMesaMakeCurrent, et glGetIntegerv. Le programme de test serait toujours saisir le système opengl32.dll à moins que j'ai spécifiquement mis la Mesa de la bibliothèque dans le même répertoire.
L'exécution de Windows l'éditeur de liens apparaît, dans mon expérience (et je suis en train de l'utiliser dans un projet publié, et il semble être au travail), à s'appuyer sur deux vérifications de base: 1) la bibliothèque des importations d'une autre bibliothèque par son nom, qui est toujours relative, si vous avez lié à l'encontre d'une norme LIB, et 2) de ne pas recharger une bibliothèque, s'il trouve une bibliothèque chargée avec le même chemin. Dans mon cas, j'ai des plugins dans plusieurs répertoires en fonction de Devil.dll; je charge qu'à partir de la DLL principale à l'aide de
LoadLibrary("DevIL.dll")
et tous les plugins utiliser cette copie sans le recharger à partir d'un autre répertoire.Maintenant, le "truc" de la partie intervient lorsque vous êtes en train de faire que sur une importées (délai de démarrage liés) de la bibliothèque. L'éditeur de liens de charger la bibliothèque pendant le chargement de l'application, donc vous devez le faire avant que. Toutefois vous parvenez à le faire juste jeu, que ce soit un lanceur qui lance le processus de suspension et injecte de la bibliothèque, une cale, de la sorte, même en remplacement d'une autre bibliothèque et le chargement dynamique de d'abord la vôtre. Je suis sûr qu'il ya un moyen plus facile, que vous pouvez probablement trouver en regardant la charge des tentatives, mais ce court-circuit apparaît fiable au moins dans mon cas d'utilisation.
OriginalL'auteur ssube
Bien que cela devrait être possible dans la fenêtre de commande, vous avez l'impression de n'avoir aucune chance.
Essayer: définir une variable dans un script (RUNNING_IN_SCRIPT=Y), puis analyse de cette variable dans votre exécutable et LoadLibrary à partir du chemin d'accès absolu de l'installation - assurez-vous d'effacer la variable lorsque vous quittez.
Sûr, il suffit d'appeler la fonction LoadLibrary lorsque la variable est défini sur "Y", ignorer que le code du contraire. Remarque ce n'est pas une bonne solution mais il faudra travailler
C'est la partie que je ne comprends pas. Disons que mon script définit une variable, puis lance mon programme en mode batch. Mon programme se lance automatiquement et charge le système opengl32.dll. Par moment mon programme arrive à la partie où il vérifie s'il a été démarré en mode batch, le système opengl32.dll a déjà chargé. Si j'essaie maintenant de faire un LoadLibrary("H:\\PATH\\TO\\mesa\\opengl32.dll"), comment peut-il remplacer le système opengl32.dll qui a déjà chargé?
charger la bibliothèque au démarrage du programme, ce qui devrait empêcher, il est nécessaire de charger la dll système
Je ne suis probablement pas vous comprendre correctement. Qu'entendez-vous par "charger la bibliothèque que le programme commence"? Je pensais que vous parliez d'insérer un LoadLibrary("H:\\PATH\\TO\\mesa\\opengl32.dll") dans le programme, mais j'ai essayé et ça ne fonctionne pas.
OriginalL'auteur KevinDTimm
Windows utilisé pour la recherche des chemins différents pour les bibliothèques dynamiques, mais en raison de la considération de sécurité, le chemin d'accès au système est recherché en premier.
Vous pouvez, cependant, le Retard de la Charge Importations pour obtenir une solution de contournement:
Si vous utilisez MSVC, vous pourriez seule la Dll que vous êtes intéressé à chargement sur votre propre avec
/DELAYIMPORT
drapeau de l'éditeur de liens.Ensuite, remplacer le retard de charge fonction d'assistance et l'utilisation
LoadLibrary
pour trouver la bonne DLL (et pas confiance au système).Après le chargement de la DLL correcte, demandez à l'assistant de fonction il suffit d'appeler l'original qui va faire tout le
GetProcAddress
d'affaires par lui-même.OriginalL'auteur assafs