2010-10-27 24 views
8

Tengo algunas dudas con respecto a cómo Windows administra la memoria de un dll.Dll Gestión de memoria

  • cuando .dll se cargan en el proceso de host , cómo se gestiona la memoria?

  • ¿Tiene .dll acceso a toda la memoria disponible para el proceso de host o solo una parte de ella? es decir, existe una limitación cuando la memoria es asignada por una función dentro del .dll?

  • ¿Las clases de AWL como cadena, vector (dinámicamente aumentando el almacenamiento) etc. usadas por el dll, funcionan sin problema aquí?

+0

Pregunta relacionada: http://stackoverflow.com/questions/2266218/ –

+0

Otra pregunta relacionada: http://stackoverflow.com/questions/1634773/ –

+0

La respuesta aceptada a esto tiene lo que necesita Creo: http : //stackoverflow.com/questions/2154939/ –

Respuesta

4

"La gestión de la memoria" es una responsabilidad dividida, por lo general. El sistema operativo dirige el espacio en grandes fragmentos al tiempo de ejecución, que luego distribuye en bits más pequeños al programa. Este espacio de direcciones puede o no tener RAM asignada. (De lo contrario, habrá un espacio de intercambio para respaldarlo)

Básicamente, cuando se carga una DLL, Windows asigna espacio de direcciones para el código y los segmentos de datos, y llama al DllMain(). El compilador de C++ habrá dispuesto llamar a ctors globales desde DllMain(). Si se trata de una DLL escrita en C++, probablemente dependa de una DLL de tiempo de ejecución C++, que a su vez dependerá de Kernel32.DLL y User32.DLL. Windows entiende tales dependencias y hará los arreglos para que se carguen en el orden correcto.

Solo hay un espacio de direcciones para una prueba, por lo que una DLL tendrá acceso a toda la memoria del proceso. Si se carga una DLL en dos procesos, habrá dos copias lógicas del código y los datos. (las copias del código y los datos de solo lectura pueden compartir la misma memoria RAM física).

Si la DLL asigna memoria usando las funciones del sistema operativo, Windows asignará la memoria al proceso desde el cual la DLL hizo esa asignación. El proceso debe devolver la memoria, pero cualquier código en el proceso puede hacerlo. Si su DLL asigna memoria usando funciones de C++, lo hará llamando al operator new en la DLL de tiempo de ejecución de C++. Esa memoria debe devolverse llamando al operator delete en la (misma) DLL de tiempo de ejecución de C++. Nuevamente, no importa quién haga eso.

Las clases de STL como vector<> se pueden crear múltiples instancias, pero no importa si se usa el mismo compilador. Todas las instancias serán sustancialmente iguales, y todas devolverán la memoria del vector a la misma función de desasignación.

Hay 2 supuestos principales en esta explicación:

  1. El EXE y sus DLL están compilados con el mismo compilador
  2. El EXE y sus DLL todo enlace contra la DLL de tiempo de ejecución C++ (es decir, no estáticamente vinculado)

La vinculación estática frente al tiempo de ejecución de C++ es útil si desea enviar un archivo EXE independiente y autónomo. Pero si ya está enviando archivos DLL, también debe mantener el tiempo de ejecución de C++ en su propia DLL.

+0

* Las clases de STL como vector <> pueden multiplicarse por instancias, pero no importa siempre que use el mismo compilador. * - Se debe agregar que no solo debe ser el mismo compilador, sino también el las mismas banderas, si las hay, se aplican a estas: '_SECURE_SCL', etc. –

3

¿El .dll tener acceso a toda la memoria disponible para el proceso de host o sólo una parte de ella? es decir, ¿hay una limitación en cuando la memoria está asignada por una función dentro del .dll?

Después de una DLL se ha cargado en el proceso de host, no hay distinción alguna por código "vivo" en la DLL vs. código "vivo" en el módulo ejecutable original. Para el proceso que se ejecuta, todos los rangos de memoria son los mismos, ya sea que provengan de una DLL o del ejecutable original.

No hay diferencias en cuanto a lo que puede hacer el código de la DLL frente a lo que puede hacer el código compilado en el módulo original de exec.

Dicho esto, hay son diferencias cuando se utiliza el montón - estos se explican en las preguntas Space_C0wb0y proporcionado los enlaces en el comments

Will clases STL como cuerdas, vector (dinámicamente aumentar el almacenamiento) etc. utilizado por el dll, funciona sin problema aquí?

Ellos serán crear problemas (las más solubles, pero aún así) si se utilizan en la interfaz de su DLL. El no (o solo en circunstancias muy excepcionales) crea problemas si no los utiliza en el nivel de interfaz DLL. Estoy seguro de que hay algunas preguntas + respuestas más específicas para esto.

Básicamente, si los usa en el nivel de interfaz, la DLL y el EXE tienen que compilarse con "exactamente" las mismas banderas, es decir, los tipos deben ser compatibles con binarios. Es decir. si los indicadores del comiler (optimización, etc.) en su DLL difieren de los del EXE de modo que un std::string se distribuye de forma diferente en la memoria en el EXE frente a la DLL, el paso de un objeto de cadena entre los dos dará como resultado un fallas o errores silenciosos (o demonios que salen volando de tu nariz).

Si solo utiliza los tipos de STL dentro de las funciones o entre las funciones internas de su DLL, entonces su compatibilidad con el EXE no es importante.

+0

"Crearán problemas (que se pueden resolver, pero aún así) si los usa en la interfaz de su archivo DLL". ¿Puede explicar más o dar un ejemplo? – SysAdmin

Cuestiones relacionadas