2009-06-27 46 views
15

Tôi đang gặp rắc rối với LoadLibrary() và nhận được một lỗi mà không có ý nghĩa với tôi:LoadLibrary() mã lỗi 127

::SetLastError(0); 

    m_hDll = ::LoadLibrary(szName); 

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

Các lỗi được 127 ("Các thủ tục quy định có thể không được tìm thấy. ") Điều đó không có ý nghĩa gì đối với tôi khi gọi hàm LoadLibrary(). Tôi chưa gọi GetProcaddress().

DLL (và ứng dụng) đều được biên dịch với VS ++ 2005 SP1.

Điều gì có thể xảy ra?

+0

Có thể không có 'DllMain' trong thư viện? Nếu nó thất bại ':: LoadLibrary'? –

+0

Nếu 'DllMain' đặt 'lỗi cuối cùng' là 127 và sau đó trả về' FALSE', thì 'lỗi cuối cùng' sẽ được ghi đè bởi hệ thống trước khi trở về từ ':: LoadLibrary'? –

Trả lời

4

Xảy ra lỗi có nghĩa là có một DLL thích hợp được tìm thấy nhưng một thủ tục xuất yêu cầu bị thiếu. Bạn có phiên bản đúng của DLL không?

Bạn có thể sử dụng dumpbin.exe để kiểm tra những hàm DLL bạn xuất và kiểm tra chính tả.

+1

Tôi chưa gọi GetProcAddress(). Xuất khẩu nào có thể bị thiếu? –

+0

@Adam: Bạn nói đúng. Ai đã bỏ phiếu +1? : \ –

2

Bạn có sự không khớp giữa thời gian chạy được sử dụng cho ứng dụng của bạn và DLL không?

Một vấn đề bị cắn tôi với VS 2005 trong quá khứ là một phần được xây dựng dưới dạng Bản dựng bản phát hành và một phần khác là bản dựng Gỡ lỗi. Những kéo trong các phiên bản khác nhau của Microsoft runtime DLLs không tương thích như bạn chỉ có thể có một nạp trong một quá trình nhất định.

Tôi nghĩ lý do bạn thấy Lỗi 127 là do tệp DLL của bạn đang tìm kiếm một hàm trong DLL thời gian tải đã tải không có ở đó vì đó là thời gian chạy sai.

0

Hai dự đoán từ tôi
1. LoadLibrary gọi DllMain của DLL được chỉ định (lần đầu tiên bạn thử và đính kèm với quy trình của bạn). Cú sút dài nhưng phải không?
2. LoadLibrary sẽ tải DLL được chỉ định và tất cả phụ thuộc của nó. Vì vậy, nếu một module phụ thuộc của DLL không thể nằm trong đường dẫn tìm kiếm mà sẽ làm cho tải thất bại - bạn có thể sử dụng để kiểm tra depends.exe - sẵn here

+0

Bạn có thể làm rõ? Có "đường dẫn tìm kiếm" cho các phụ thuộc của DLL bao gồm thư mục của DLL đang được tải không? Hoặc chỉ là thư mục của ứng dụng? (Hay không, hoặc cả hai?) –

19

Chúng ta hãy bước này bằng cách bước:

  1. Thông báo lỗi có nghĩa là dll được tìm thấy nhưng thiếu chức năng bắt buộc. (Jitter là đúng.) Điều này ngụ ý rằng bạn có dll bạn cần, nhưng không phải là phiên bản đúng. (Davefiddes là đúng, mặc dù vấn đề có thể là bất kỳ dll, không chỉ thư viện thời gian chạy của Microsoft. Và, ít nhất là cho các bản cập nhật lớn, Microsoft cung cấp cho các thư viện thời gian chạy các tên khác nhau, vì vậy trong trường hợp đó nó sẽ không là vấn đề.)

  2. Điều này không có ý nghĩa, vì không có chức năng nào được yêu cầu từ dll đang được tải. (Adam là đúng.)

  3. Do đó, chức năng bị thiếu được mong đợi sẽ không được tìm thấy trong dll đang được tải bởi lệnh LoadLibrary, nhưng trong một dll phụ thuộc đang được nạp ngầm cùng một lúc, vì dll đầu tiên yêu cầu nó. (Zebrabox là gần gũi.)

  4. Một dll phụ thuộc là một dll đó là "tĩnh" liên quan đến thư viện được nạp một cách rõ ràng, thông qua một thư viện nhập khẩu, hoặc file .lib, bao gồm trên bước mối liên kết của dll nạp một cách rõ ràng . (Tôi đặt cược bạn không biết rằng một "thư viện liên kết động" có thể được "liên kết tĩnh" Vâng, bây giờ bạn làm.)

  5. Nếu bạn có nhiều phiên bản của cùng một dll trong các thư mục khác nhau, thì đây cũng có thể là vấn đề đường dẫn tìm kiếm (như zebrabox gợi ý). Thứ tự tìm kiếm đường dẫn dll là một chủ đề phức tạp trong chính nó: xem http://msdn.microsoft.com/en-us/library/ms682586(VS.85).aspx. Nó phụ thuộc vào hệ điều hành, trong số những thứ khác. Đặt cược an toàn nhất, khi thực tế, là đặt tất cả các dll vấn đề tiềm năng vào cùng thư mục với exe của bạn.

  6. Các dll phụ thuộc cũng có thể có các dll phụ thuộc của riêng chúng, điều này có thể khiến cho vấn đề này rất khó giải quyết. Phụ thuộc có thể giúp đỡ, nhưng nếu không, hãy thử filemon. Dll cuối cùng được đọc thành công trước khi thông báo lỗi của bạn là một phiên bản sai.

0

Tôi đã nhận được cùng một mã lỗi sau khi gọi hàm LoadLibrary(). Cuối cùng tìm thấy thông qua walker phụ thuộc mà một số phụ thuộc của module (szName) bị thiếu.

4

Cài đặt Công cụ gỡ lỗi và chạy gflags -i your_application.exe +sls. Sau đó thực hiện ứng dụng theo trình gỡ rối để nắm bắt các dấu vết của trình nạp.

0

Tôi khuyên bạn nên sử dụng Dependency Walker để tìm hiểu phương thức nào bị thiếu hoặc DLL nào là bắt buộc hoặc bị thiếu.

5

Công cụ Microsoft gflags sẽ luôn cho bạn biết chính xác phụ thuộc nào không tải được và tại sao.

Chạy gflags -i your_application.exe +sls. Sau đó thực thi ứng dụng dưới trình gỡ rối để chụp loader traces.

gflags là một phần của Debugging Tools - bạn có thể đăng ký C:\Program Files (x86)\Windows Kits\10\Debuggers\x64 để xem bạn đã có nó chưa. Bạn có thể thêm thư mục đó vào đường dẫn của bạn, hoặc chỉ thực thi gflags từ thư mục đó trong cmd.exe.

Ví dụ: sau khi chạy gflags, hãy đặt một điểm ngắt trên cuộc gọi ::LoadLibrary(_T("foo")) và bước qua nó trong khi tìm kiếm lỗi trình tải trong cửa sổ đầu ra Visual Studio của bạn, ví dụ:

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 

Điều này có nghĩa rằng trong thời gian tải của foo.dll, phụ thuộc bar.dll được nhập khẩu và nhập khẩu bar.dll thất bại.

Nhập phụ thuộc không thành công do quy trình [email protected][email protected]@[email protected] bị thiếu - bạn có thể demangle rằng đến public: void __cdecl vis_DollarMap::SetObject(int,void * __ptr64) __ptr64.

Bạn có thể có phiên bản sai của phụ thuộc - có thể bạn cần phải xây dựng lại phụ thuộc để cập nhật.


Chạy gflags -i your_application.exe -sls sau đó để tắt dấu vết bộ tải.

Các vấn đề liên quan