2010-04-07 4 views
2

J'ai un problème étrange. J'ai un projet en C++ qui est essentiellement un wrapper pour une DLL tierce partie comme ceci:Problème JNI lors de l'appel d'une bibliothèque native qui charge une autre bibliothèque native

MyLibrary
--loads DLL_A
---- charges DLL_B

que je charge DLL_A avec LoadLibrary(), enveloppement plusieurs de ses fonctions et générer ma propre DLL. J'ai testé ceci dans un projet C++ et un projet C#. Les deux font tout ce qu'ils sont supposés faire: charger DLL_A, effectuer quelques appels de fonction et charger indirectement DLL_B. Le problème est quand je construis une DLL pour Java et fais les appels par l'intermédiaire de JNI. Tout fonctionne comme il se doit (pas java.lang.UnsatisfiedLinkError), mais quand il est temps pour DLL_A de charger DLL_B cela ne fonctionne pas. À partir du débogage, le chargement de DLL_B se produit sur un appel de fonction dans DLL_A qui prend un rappel. Appelé à partir de Java, cet appel de fonction semble échouer (le pointeur de fonction est correct et l'appel réel se termine sans incident), et une fenêtre pop-up bizarre indique que DLL_B n'a pas pu être chargée et mon programme est en attente un rappel qui n'arrive jamais. Je peux charger DLL_B de manière explicite (à partir de Java et de C++) et j'ai vérifié chaque chemin possible, variable de chemin, et j'ai essayé de placer les dlls partout pour voir si ça pouvait être drôle. Je suis à peu près sûr que ce n'est pas un problème de chemin. En fin de compte, je ne sais pas comment DLL_A charge DLL_B et je n'arrive pas à comprendre pourquoi tout fonctionne bien en C++ et en C#, mais pas en Java. Je suis absolument déconcerté. Cela pourrait toujours être quelque chose de spécifique à ma configuration (bien que j'aie regardé aussi fort que possible), mais je lance ce scénario pour voir si quelqu'un a rencontré un problème similaire.

-Dave

Répondre

2

Il n'y a que deux façons dont une DLL peut charger un autre dans Windows - soit ils le font en utilisant explicitement LoadLibrary() ou il est implicitement en liant la première DLL à la bibliothèque d'importation de la seconde. Vous devriez pouvoir utiliser Dependency Walker pour savoir si DLL_B est une dépendance de DLL_A ou non. L'exécution de depwalker vous montrera également si DLL_B est sur le chemin s'il est implicitement lié ou non. Je voudrais également exécuter depwalker sur DLL_B pour m'assurer qu'il n'y a pas de dépendances surprenantes pour DLL_B - le problème que vous voyez pourrait bien être causé par le fait que DLL_B ne puisse pas charger l'une de ses dépendances, pas par DLL_A échouer à trouve DLL_B. IIRC Windows va scanner le PATH pour les bibliothèques implicitement liées, vérifiez donc si votre invocation de votre processus java joue avec le chemin. La documentation pour LoadLibrary explique comment LoadLibrary recherche une DLL.

Vous avez dit que vous avez réussi à charger directement DLL_B à partir de Java; Lorsque vous faites cela et ensuite appelez via DLL_A, le mécanisme de rappel commence-t-il à fonctionner? Cela pourrait être une solution de rechange un peu laide pour le moment.

Questions connexes