2009-06-27 129 views
15

我在與調用LoadLibrary(麻煩),並得到一個錯誤,沒有任何意義對我說:調用LoadLibrary()錯誤代碼127

::SetLastError(0); 

    m_hDll = ::LoadLibrary(szName); 

    if (m_hDll == NULL) // Failure to load the DLL. 
    { 
     DWORD err = GetLastError(); 
    } 

的錯誤127(「指定的程序不能找到。「)對LoadLibrary()的調用我沒有任何意義。我還沒有調用GetProcaddress()。

DLL(和應用程序)都是用VS ++ 2005 SP1編譯的。

可能會出現什麼問題?

+0

也許圖書館裏沒有`DllMain`?它應該失敗`:: LoadLibrary`? – 2010-03-17 17:21:19

+0

如果`DllMain`將'最後一個錯誤'設置爲127,然後返回'FALSE`,那麼在':: LoadLibrary`返回之前系統會覆蓋'最後一個錯誤'嗎? – 2010-03-17 17:25:29

回答

4

錯誤消息意味着找到了合適的DLL,但缺少所需的過程導出。你有正確的DLL版本嗎?

您可以使用dumpbin.exe來檢查DLL導出的功能並檢查拼寫。

+1

我還沒有調用過GetProcAddress()。什麼導出可能會丟失? – 2009-06-27 17:22:02

2

您的應用程序和DLL使用的運行時間不匹配嗎?

過去,VS 2005讓我感到困惑的一個問題是,其中一部分構建爲發佈版本,另一部分構建爲調試版本。這些拉動不兼容的Microsoft運行時DLL的不同版本,因爲只能在給定進程中加載​​一個DLL。

我認爲你看到錯誤127的原因是因爲你的DLL在加載的運行時DLL中尋找一個不存在的函數,因爲它是錯誤的運行時。

0

我的兩個猜測
1. LoadLibrary調用指定DLL的DllMain(第一次嘗試並附加到您的過程)。遠射,但它在那裏?
2. LoadLibrary將加載指定的DLL及其所有依賴項。因此,如果DLL的依賴模塊不能位於這將導致加載失敗的搜索路徑 - 你可以用於depends.exe檢查 - 可here

19

讓我們一步一步來:

  1. 錯誤消息表示找到了dll,但缺少必需的功能。 (抖動是正確的。)這意味着你有你需要的DLL,但不是正確的版本。 (Davefiddes是對的,雖然問題可以是任何DLL,而不僅僅是Microsoft運行時庫,並且,至少對於主要更新,Microsoft爲其運行時庫提供了不同的名稱,所以在這種情況下,這不是問題。)

  2. 這沒有意義,因爲沒有函數被請求從被加載的dll。 (亞當是對的)

  3. 因此,缺少的函數應該被發現不在被LoadLibrary命令顯式加載的dll中,而是在一個依賴的dll中被同時隱式加載,因爲第一個DLL需要它。 (Zebrabox已關閉。)

  4. 依賴的dll是一個dll,它「靜態」鏈接到正在顯式加載的庫,通過導入庫或.lib文件包含在顯式加載的dll的鏈接器步驟中。 (我敢打賭,你不知道一個「動態鏈接庫」可能會「靜態鏈接」。好吧,現在你已經做到了。)

  5. 如果您在不同的文件夾同一個DLL的多個版本,那麼這可能也是一個搜索路徑的問題(如zebrabox建議)。 Dll路徑搜索順序本身是一個複雜的主題:請參閱http://msdn.microsoft.com/en-us/library/ms682586(VS.85).aspx。這取決於操作系統等。最實際的最安全的方法是將所有潛在的問題DLL放在與exe相同的文件夾中。

  6. 相關DLL也可以有自己的依賴DLL,它可以使這個問題很難解決。取決於可能會有幫助,但如果沒有,請嘗試使用filemon。在錯誤消息之前成功讀取的最後一個dll是錯誤版本的dll。

0

我在調用LoadLibrary()後得到相同的錯誤代碼。最後通過依賴walker發現模塊(szName)的一些依賴關係丟失。

4

安裝調試工具和運行gflags -i your_application.exe +sls。之後,在調試器下執行應用程序以捕獲加載程序跟蹤。

5

微軟gflags工具會隨時告訴你到底是什麼依賴性無法加載和原因。

運行gflags -i your_application.exe +sls。之後,在調試器下執行應用程序以捕獲loader traces

gflags是Debugging Tools的一部分 - 您可以檢查C:\Program Files (x86)\Windows Kits\10\Debuggers\x64以查看是否已擁有它。您可以將該目錄添加到您的路徑中,或者僅在cmd.exe中執行該目錄中的gflags。

例如,在運行gflags之後,在::LoadLibrary(_T("foo"))調用中放置一個斷點並在您的Visual Studio輸出窗口中查找加載器錯誤時跳過它,例如,

4b00:396c @ 479194074 - LdrpSnapThunk - ERROR: Procedure "[email protected][email protected]@[email protected]" could not be located in DLL "bar.dll" 
First-chance exception at 0x0000000077307EF8 (ntdll.dll) in your_application.exe: 0xC0000139: Entry Point Not Found. 
4b00:396c @ 479194074 - LdrpGenericExceptionFilter - ERROR: Function LdrpSnapIAT raised exception 0xc0000139 
    Exception record: .exr 0000000000129070 
    Context record: .cxr 0000000000128B80 
4b00:396c @ 479194074 - LdrpHandleOneOldFormatImportDescriptor - ERROR: Snapping the imports from DLL "C:\test\64Debug\foo.DLL" to DLL "C:\test\64Debug\bar.dll" failed with status 0xc0000139 

這意味着foo.dll負載時,依賴bar.dll是進口,而進口bar.dll失敗。

的依賴進口失敗,因爲程序[email protected][email protected]@[email protected]不見了 - 你可以demangle,爲public: void __cdecl vis_DollarMap::SetObject(int,void * __ptr64) __ptr64

你可能有依賴的錯版 - 也許你需要重建的依賴得到它最新的。


之後運行gflags -i your_application.exe -sls禁用加載程序跟蹤。