2010-04-07 54 views
2

我有點奇怪的問題。我有在C++中的一個項目,基本上是一個第三方DLL像這樣的包裝:調用加載另一個本機庫的本地庫時的JNI問題

在MyLibrary
--loads DLL_A
----負載DLL_B

我加載DLL_A與調用LoadLibrary(),包它的幾個函數並生成我自己的DLL。我已經在C++項目和C#項目中測試過了。兩者都做他們應該做的一切:加載DLL_A,進行幾個函數調用,並間接加載DLL_B。問題是當我爲Java構建一個DLL並通過JNI進行調用時。所有東西都像它應該運行(沒有java.lang.UnsatisfiedLinkError),但是當DLL_A加載DLL_B時它不起作用。 從調試開始,DLL_B的加載發生在DLL_A中的一個函數調用中,該函數需要回調。當從Java調用時,這個函數調用似乎失敗了(函數指針很好,實際的調用沒有中斷),並且我得到一個奇怪的彈出窗口,說DLL_B加載失敗,我的程序仍在等待一個從未發生過的回調。我可以明確地加載DLL_B(無論是從Java還是從C++),並且我已經檢查了每個可能的路徑,路徑變量,並試圖將DLL放在任何地方,以查看它是否可能看起來有趣。我很確定這不是路徑問題。

最終我不知道DLL_A是如何加載DLL_B的,我無法弄清楚爲什麼在C++和C#中一切正常,但在Java中卻不行。我絕對不知所措。它可能仍然是我的設置特有的東西(儘管我看起來很難看),但是我將這種情況放在那裏,看看是否有人遇到過類似的問題。

-Dave

回答

2

其實只有兩種方式一個DLL可以加載一個又一個在Windows - 他們要麼是明確使用LoadLibrary()做,或者通過鏈接到的第二個的導入庫的第1個DLL是隱式。您應該能夠使用Dependency Walker來確定DLL_B是否是DLL_A的依賴關係。如果DLL_B是隱式鏈接的,則運行depwalker也會顯示DLL_B是否在路徑上。

我也會在DLL_B上運行depwalker以確保DLL_B沒有令人意外的依賴關係 - 您看到的問題很可能是由於DLL_B無法加載其依賴項之一造成的,而不是DLL_A無法加載找到DLL_B。

IIRC Windows將掃描隱式鏈接庫的PATH,因此請檢查您的java進程的調用是否與路徑一起使用。 LoadLibrary的文檔說明了LoadLibrary如何掃描DLL。

你說你設法從Java直接加載DLL_B;當你這樣做,然後通過DLL_A調用,回調機制開始工作?暫時這可能是一個有點醜陋的解決方法。