2009-06-27 14 views
15

Ho problemi con LoadLibrary() e ottenere un errore che non ha senso per me:LoadLibrary() il codice di errore 127

::SetLastError(0); 

    m_hDll = ::LoadLibrary(szName); 

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

L'errore è 127 ("La procedura specificata non è stato possibile trovato. ") Non ha alcun senso per me in una chiamata a LoadLibrary(). Non ho ancora chiamato GetProcaddress().

La DLL (e l'applicazione) sono entrambi compilati con VS ++ 2005 SP1.

Cosa potrebbe andare storto?

+0

Forse non ci sono 'DllMain' nella libreria? Dovrebbe fallire ':: LoadLibrary'? –

+0

Se 'DllMain' imposta'ultimo errore 'come 127 e poi restituisce' FALSE', l'' ultimo errore 'verrà sovrascritto dal sistema prima di tornare da ':: LoadLibrary'? –

risposta

4

Il messaggio di errore indica che è stata trovata una DLL appropriata ma manca un'esportazione della procedura richiesta. Hai la versione giusta della DLL?

È possibile utilizzare dumpbin.exe per verificare le funzioni esportate dalla DLL e controllare l'ortografia.

+1

Non ho ancora chiamato GetProcAddress(). Quale esportazione potrebbe mancare? –

+0

@Adam: hai ragione. Chi ha votato +1? : \ –

2

Hai una discrepanza tra i tempi di esecuzione della tua app e della DLL?

Un problema che mi ha morso con VS 2005 in passato è che una parte è costruita come una build di rilascio e l'altra come una build di debug. Questi pull in diverse versioni delle DLL runtime di Microsoft che sono incompatibili in quanto è possibile avere solo uno caricato in un determinato processo.

Penso che il motivo per cui si vede Errore 127 è perché la DLL sta cercando una funzione nella DLL di runtime caricata che non è lì perché è il runtime sbagliato.

0

Due ipotesi da parte mia
1. LoadLibrary chiama il DllMain della DLL specificata (la prima volta che si tenta di collegarsi al processo). Campo lungo ma è lì?
2. LoadLibrary carica la DLL specificata e tutte le sue dipendenze. Quindi, se un modulo dipendente della DLL non può essere individuato nel percorso di ricerca che farà sì che il carico di fallire - è possibile utilizzare per controllare Depends.exe - disponibile here

+0

Si prega di chiarire? Il "percorso di ricerca" per le dipendenze della DLL include la directory della DLL che viene caricata? O solo la directory dell'applicazione? (O nessuno dei due, o entrambi?) –

19

Prendiamo questo passo per passo:

  1. Il messaggio di errore indica che è stata trovata la DLL ma manca una funzione richiesta. (Jitter ha ragione). Ciò implica che hai la DLL di cui hai bisogno, ma non la versione giusta. (Davefiddes ha ragione, anche se il problema può essere qualsiasi DLL, non solo la libreria runtime di Microsoft. E, almeno per gli aggiornamenti principali, Microsoft fornisce le sue librerie di runtime nomi diversi, quindi in tal caso non sarebbe un problema.)

  2. Questo non ha senso, perché non è stata richiesta alcuna funzione dalla DLL che si sta caricando. (Adamo ha ragione.)

  3. Pertanto, la funzione mancante era prevista non nella DLL che viene caricata in modo esplicito dal comando LoadLibrary, ma in una DLL dipendente che viene caricata implicitamente allo stesso tempo, perché la prima DLL lo richiede. (Zebrabox era vicino.)

  4. Una DLL dipendente è una DLL che è "statico" collegato alla libreria di essere esplicitamente caricato, tramite una libreria di importazione, o un file lib, incluso sul gradino linker della dll esplicitamente caricata . (Scommetto che non sapevi che una "biblioteca di link dinamici" potrebbe essere "collegata staticamente". Bene, ora lo fai.)

  5. Se si hanno più versioni della stessa dll in diverse cartelle, questo potrebbe anche essere un problema di percorso di ricerca (come suggerisce zebrabox). L'ordine di ricerca del percorso Dll è di per sé un argomento complicato: vedere http://msdn.microsoft.com/en-us/library/ms682586(VS.85).aspx. Dipende dal sistema operativo, tra le altre cose. La scommessa più sicura, dove pratico, consiste nel mettere tutte le potenziali dll di problemi nella stessa cartella del tuo exe.

  6. Le dll dipendenti possono anche avere le proprie DLL dipendenti, il che può rendere molto difficile la risoluzione di questo problema. Dipende potrebbe aiutare, ma se non lo fa, prova Filemone. L'ultima DLL che viene letta correttamente prima del tuo messaggio di errore è quella che è la versione sbagliata.

0

Ho ricevuto lo stesso codice di errore dopo aver chiamato LoadLibrary(). Finalmente trovato tramite Dipendente Walker che mancavano alcune dipendenze del modulo (szName).

4

Installare gli strumenti di debug ed eseguire gflags -i your_application.exe +sls. Successivamente eseguire l'applicazione sotto il debugger per acquisire le tracce del caricatore.

0

Suggerirei di utilizzare Dependency Walker per scoprire quale metodo è mancante o quali DLL sono richieste o mancanti.

5

Lo strumento Microsoft gflags ti dirà sempre esattamente quale tipo di carico non viene caricato e perché.

Corsa gflags -i your_application.exe +sls. Successivamente eseguire l'applicazione sotto il debugger per acquisire lo loader traces.

gflags fa parte di Debugging Tools - è possibile effettuare il check-in C:\Program Files (x86)\Windows Kits\10\Debuggers\x64 per vedere se ce l'hai già. Puoi aggiungere quella directory al tuo percorso, o semplicemente eseguire gflags da quella directory in cmd.exe.

Ad esempio, dopo aver eseguito gflag, inserire un punto di interruzione nella chiamata ::LoadLibrary(_T("foo")) e scavalcarlo mentre si cercano errori di caricamento nella finestra di output di Visual Studio, ad es.

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 

Questo significa che durante il carico di foo.dll, la dipendenza bar.dll è stato importato, e l'importazione bar.dll fallito.

L'importazione delle dipendenze non è riuscita perché mancava la procedura [email protected][email protected]@[email protected] - è possibile eseguire demangle in public: void __cdecl vis_DollarMap::SetObject(int,void * __ptr64) __ptr64.

Probabilmente hai la versione sbagliata di una dipendenza - forse è necessario ricostruire la dipendenza per aggiornarla.


Eseguire gflags -i your_application.exe -sls in seguito per disabilitare le tracce del caricatore.

Problemi correlati