2009-12-08 35 views
7

Ok, así que éste es un poco largo de explicar tan desnudo conmigo ..C++: Carga de un archivo EXE como un archivo DLL, vftable problema local de

Me han llamado un exe test.exe el que se utiliza por lo general como un soporte sola aplicación. Quiero utilizar este exe como un módulo (un dll) dentro de otra aplicación, app.exe.

El código en test.exe hace algo muy simple como:

void doTest() 
{ 
    MyClass *inst = new MyClass(); 
    inst->someMethod(); 
} 

Dónde someMethod() es virtual y MyClass tiene un d'tor virtual.
doTest() se exporta desde test.exe y, por lo tanto, se crea una lib llamada test.lib
app.exe está vinculado con esta lib para cargar estáticamente.exe cuando se inicia.

Cuando ejecuto test.exe autónomo, funciona bien pero cuando lo ejecuto cargado desde app.exe se bloquea.
Entrando en el código con el depurador reveló que el bloqueo está en la llamada al método virtual. Resulta que el vftable de alguna manera va mal.

Después de algunas investigaciones resulta que cuando se ejecuta el código dentro del constructor de MyClass, el vftable es una cosa, pero cuando la llamada a new devuelve es reemplazada por otra cosa llamada "local vftable". Encontré this obscure discussion about why this is.

Después de aproximadamente un día de depuración, se me ocurrió que los punteros en este "local vftable" son los mismos en ambos casos, cuando test.exe es independiente y cuando se carga como un módulo. Esto no puede ser correcto porque test.exe se carga en una dirección diferente ...
Para probar esta teoría, cambié la dirección de carga en las opciones del enlazador a la que se carga test.exe cuando está en app.exe y ahora, he aquí, todo funciona.

Obviamente, esta no es una solución permanente porque la próxima vez que se pueda ocupar esta dirección seleccionada aleatoriamente, se volverá a producir el mismo problema.

Así que mi pregunta: ¿Por qué este "local vftable" está relacionado con la dirección de carga estática del exe? cargar un exe como un módulo es algo malo? ¿Por qué el exe supone que está cargado en su dirección estática?

Solo por contexto: todo esto se hace con MSVC 2008, Windows XP x64.

Respuesta

3

La solución que acabo de usar es simplemente agregar una configuración de compilación y compilar el exe como un dll real en lugar de forzarlo a actuar como tal.

usando /fixed:no no resolvió el problema por alguna razón.

Otra diferencia entre exes y DLL es que el punto de entrada es diferente. el punto de entrada de un DLL es DllMain, donde como un exe tiene su punto de entrada en el CRT que eventualmente llama a main() o WinMain().

4

VC++ elimina la información de reubicación de .exes de forma predeterminada porque normalmente no es necesario que sean reubicables.

Puede forzarlo a retener la información de reloc con/fixed: no. Ver: http://msdn.microsoft.com/en-us/library/w368ysh2.aspx

+2

Lo intenté pero no parece tener ningún efecto por alguna razón – shoosh

Cuestiones relacionadas