2010-05-27 11 views
6

Ho una DLL nativa che è un plug-in per un'applicazione diversa (una che ho essenzialmente il controllo a zero). Tutto funziona perfettamente finché non collego con un file .lib aggiuntivo (collega la mia DLL a un'altra DLL denominata). Questo file contiene alcune API aggiuntive dall'applicazione padre che vorrei utilizzare. Non ho nemmeno scritto alcun codice per utilizzare nessuna delle funzioni esportate, ma solo il collegamento in questa nuova DLL sta causando problemi. In particolare, viene visualizzato il seguente errore quando si tenta di eseguire il programma:Problemi di importazione DLL Win32 (DllMain)

L'applicazione non è stata inizializzata correttamente (0xc0000025). Fare clic su OK per terminare l'applicazione.

Credo di aver letto da qualche parte che questo è in genere dovuto a una funzione DllMain che restituisce FALSE. Inoltre, il seguente messaggio viene scritto sullo standard output:

ERRORE: allocazione della memoria tentato prima dell'inizializzazione componente

Io sono quasi al 100% sicuro che questo messaggio di errore sta venendo dall'applicazione e non è un certo tipo di Errore di Windows.

Guardando in questo un po 'di più (aka agitando intorno e lanciando ogni interruttore io sappia) ho collegato con/MAP acceso e ha trovato questo nel file .map risultante:

0001:000af220  [email protected]@Z    00000001800b0220 f ABQSMABasCoreUtils_import:ABQSMABasCoreUtils.dll 
0001:000af226  [email protected][email protected]    00000001800b0226 f ABQSMABasCoreUtils_import:ABQSMABasCoreUtils.dll 
0001:000af22c  [email protected][email protected]   00000001800b022c f ABQSMABasCoreUtils_import:ABQSMABasCoreUtils.dll 
0001:000af232  [email protected]@Z    00000001800b0232 f ABQSMABasCoreUtils_import:ABQSMABasCoreUtils.dll 

Se undecorate quelli nomi utilizzando "undname" danno la seguente (stesso ordine):

void __cdecl operator delete(void * __ptr64) 
void * __ptr64 __cdecl operator new(unsigned __int64) 
void * __ptr64 __cdecl operator new[](unsigned __int64) 
void __cdecl operator delete[](void * __ptr64) 

io non sono sicuro di aver capito come qualsiasi cosa, da ABQSMABasCoreUtils.dll può esistere all'interno di questo file .map o perché la mia DLL è anche il tentativo di caricare ABQSMABasCoreUtils.dll se non ho alcun codice che referenzia es questa DLL. Qualcuno può aiutarmi a mettere insieme queste informazioni e scoprire perché questo non funziona? Per quello che vale ho confermato tramite "dumpbin" che l'applicazione genitore importa , quindi viene caricato indipendentemente. Ho anche provato a caricare in ritardo questa DLL nella mia DLL, ma questo non ha modificato i risultati.

EDIT

Ho ricontrollato e tutti i file coinvolti sono 64 bit.

+1

Hai provato a utilizzare 'LoadLibrary' invece del collegamento statico della libreria di importazione? Se lo fai, l'applicazione principale è già inizializzata e hai così qualche vantaggio. – Oleg

+0

Ci ho pensato, ma finirò per utilizzare una grande quantità di funzioni da questa libreria. Non dovrò usare GetProcAddress per ognuno? Preferirei evitarlo, se possibile. – brady

+1

C0000025 = STATUS_NONCONTINUABLE_EXCEPTION. Prova a eseguire l'applicazione in windbg e vedere dove si blocca; forse questo ti darà un suggerimento. – Luke

risposta

5

Ho appena avuto esattamente lo stesso problema. Questo è un problema con l'API di Abaqus piuttosto che con il caricamento di DLL.

Penso che sia perché l'API Abaqus sovrascrive le funzioni nuove ed eliminate (come sembra aver notato). Se si chiama di nuovo o eliminare nel programma prima inizializzare l'API Abaqus, come ad esempio chiamando odb_initializeAPI(); allora viene visualizzato l'errore

: allocazione della memoria tentato prima dell'inizializzazione componente

messaggio di errore e il programma si blocca .

Nel mio programma, chiamando odb_initializeAPI(); prima del primo new risolto il problema.

+1

È passato un po 'di tempo da quando ho risolto questo problema, ma ho avuto un altro problema. In realtà stavo accedendo all'ODB in una subroutine utente, quindi stavo usando getActiveOdb(). Stavo ricevendo questo errore perché stavo compilando una dipendenza su msvcr90.dll e Abaqus stava usando msvcr80.dll. Ma sono contento che tu abbia postato quanto sopra: è difficile trovare un aiuto rapido online per subroutine utente e post processori di Abaqus. – brady

+0

@brady Come hai identificato e risolto il problema delle dipendenze? Credo che 'msvcr100.dll' sia in conflitto con' msvcr80.dll' nel mio programma. Gradirei davvero un aiuto in questo. – Derek

+1

Non ricordo come l'ho identificato - probabilmente ho usato l'utility "dumpbin/imports" e ho notato le librerie di runtime ridondanti di C++. Per risolvere il problema, ho dovuto creare con Visual C++ 8.0 (Visual Studio 2005) che era il compilatore C++ supportato per quella versione di Abaqus. È possibile visualizzare i compilatori supportati qui: [Requisiti di sistema Abaqus] (http://www.3ds.com/support/certified-hardware/simulia-system-information/). Scegli la versione appropriata e fai clic su Requisiti di sistema, scegli la tua piattaforma e cerca i requisiti del compilatore C++. – brady

0

L'ABQSMABasCoreUtils.dll sembra importare le funzioni a 64 bit. La tua DLL è anche a 64 bit? In caso contrario, questo è il problema: non è possibile combinare DLL compilate per architetture diverse nello stesso processo.

+0

In questo caso, il codice non riuscirà a compilare - non fallire in fase di runtime. –

2

Beh, certo che farai riferimento alle importazioni di quella libreria. Difficile scrivere un programma C++ senza utilizzare l'operatore new o delete. Trattare con un software di terze parti che ritenga necessario ignorare la versione CRT di quegli operatori è abbastanza difficile, impossibile quando non ti consente di chiamarli finché non crede che sia il momento giusto. Abbandona ogni speranza o cerca aiuto dal venditore.

+1

È comune che programmi C++ di grandi dimensioni ignorino tali operatori comuni? Sembra abbastanza sciocco. È possibile aggirare questo con/DEFAULTLIB? – brady

+2

È comune solo nei programmi stupidi e nelle librerie di classi di stile delle basi che contano su tutto il codice che viene collegato a esse. Non puoi aggirarlo. L'hacking del .lib causerà solo dolore quando un codice usa l'allocatore e l'altro codice no. Questa è una perdita di memoria automatica o AV. –

1

Una delle possibili cause di un errore durante il caricamento di ABQSMABasCoreUtils.dll è che non è stato possibile trovare alcun modulo di dipendenza (DLL con ritardo di caricamento incluso). Utilizzare Dipendente Walker (vedere http://www.dependencywalker.com/) per esaminare tutte le dipendenze di ABQSMABasCoreUtils.dll.

ho due suggerimenti:

  1. verificare che è possibile caricare ABQSMABasCoreUtils.dll rispetto di LoadLibrary. Non è necessario chiamare alcuna funzione da ABQSMABasCoreUtils.dll. Utilizzo di LoadLibrary Non vedo come soluzione finale. È solo un test diagnostico. Con il test puoi verificare se hai qualche problema generale nel caricare ABQSMABasCoreUtils.dll nel tuo programma o hai qualche tipo di problema di inizializzazione del processo.
  2. Se il caricamento di ABQSMABasCoreUtils.dll con riferimento a LoadLibrary non è riuscito, quindi utilizzare la funzione di profilazione di Dependency Walker al protocollo di tutte le chiamate effettuate durante il caricamento di ABQSMABasCoreUtils.dll. Un altro modo sarebbe l'utilizzo di Process Monitor (vedere http://technet.microsoft.com/en-us/sysinternals/bb896645.aspx) per tracciare quali operazioni di file e registro verranno eseguite durante il caricamento di ABQSMABasCoreUtils.dll.

Se LoadLibrary non è fallito, si ha davvero un problema di inizializzazione delle DLL. In genere il problema esiste se una DLL all'interno di DllMain tenta di utilizzare una funzione da un'altra DLL non ancora inizializzata (non ancora restituita da DllMain). Prima di iniziare una diagnosi di questo problema, dovremmo cercare di escludere problemi più semplici con LoadLibrary.

Problemi correlati