Ok, quindi questo è un po 'nervosa lungo da spiegare così nudo con me ..C++: Caricamento di un file EXE come DLL, problema vftable locale
ho un exe chiamato test.exe che di solito è utilizzato come supporto applicazione sola. Voglio usare questo exe come un modulo (una DLL) all'interno di un'altra applicazione, app.exe.
Il codice in test.exe fa qualcosa di veramente semplice come:
void doTest()
{
MyClass *inst = new MyClass();
inst->someMethod();
}
Dove someMethod()
è virtuale e MyClass ha una d'tor virtuale.
doTest()
viene esportato da test.exe e quindi viene creato un lib chiamato test.lib
app.exe è collegato con questo lib per caricare staticamente test.exe all'avvio.
Quando eseguo test.exe autonomamente, funziona correttamente ma quando viene eseguito caricato da app.exe si blocca.
L'introduzione nel codice con il debugger ha rivelato che l'arresto si trova nella chiamata al metodo virtuale. Si scopre che il vftable in qualche modo va male.
Dopo alcune indagini si scopre che quando il codice all'interno del costruttore di MyClass è in esecuzione, il vftable è una cosa, ma quando la chiamata a new
rendimenti è sostituirlo con qualcos'altro chiamato "vftable locale". Ho trovato this obscure discussion about why this is.
Dopo circa un giorno di debug mi è venuto in mente che i puntatori in questo "vftable locale" sono gli stessi in entrambi i casi, quando test.exe è autonomo e quando viene caricato come modulo. Questo non può essere corretto perché test.exe è caricato in un indirizzo diverso ...
Per testare questa teoria ho cambiato l'indirizzo di caricamento nelle opzioni del linker a quello in cui è caricato test.exe quando è in app.exe e ora, ecco, tutto funziona.
Ovviamente, questa non è una soluzione permanente perché la prossima volta questo indirizzo selezionato a caso potrebbe essere occupato e lo stesso problema si ripresenterà.
Quindi la mia domanda: perché questo "locale vftable" è legato all'indirizzo di caricamento statico dell'exe? sta caricando un exe come un modulo una cosa negativa? perché l'exe assume che sia caricato nel suo indirizzo statico?
Solo per il contesto: tutto questo è stato eseguito con MSVC 2008, Windows XP x64.
L'ho provato ma non sembra avere alcun effetto per qualche motivo – shoosh