2009-07-24 8 views
11

¿Tiene una biblioteca compartida de C++ su propio espacio de memoria? ¿O comparte el proceso de llamador 'uno?Espacio de memoria de bibliotecas compartidas

Tengo una biblioteca compartida que contiene algunas clases y funciones de contenedor. Una de esta función de envoltura es un poco:

libXXX_construct() que inicializa un objeto y devuelve el puntero a dicho objeto.

Una vez que uso libXXX_construct() en un programa de llamada donde se coloca el objeto, ¿está en el espacio de la memoria "llamante" o está en el espacio de la memoria de la biblioteca?

Respuesta

7

Una instancia vinculada de la biblioteca compartida comparte el espacio de memoria de la instancia del ejecutable que se vinculó a él, directa o indirectamente. Esto es cierto tanto para Windows como para los sistemas operativos UN * X-like. Tenga en cuenta que esto significa que las variables estáticas en las bibliotecas compartidas no son una forma de comunicación entre procesos (algo que mucha gente piensa).

+0

¿Qué sucede si el ejecutable que está vinculado a la biblioteca compartida también es una biblioteca compartida? Es el objeto creado en el .so interno en el mismo espacio de memoria de la principal (que llama a este último .so) – nick2k3

+0

Solo hay un espacio de memoria. –

+0

Muchas gracias. – nick2k3

2

Todas las bibliotecas compartidas comparten el espacio de la memoria virtual de su proceso . (Incluyendo el principal en sí ejecutable)

0

existe Su objeto en el espacio de memoria de la persona que llama (de hecho, el espacio de una memoria compartida entre la biblioteca y el archivo ejecutable principal)

0

El espacio de direcciones de la cuota para que pueda compartir punteros, sin embargo no comparten el asignador (al menos no en las ventanas).

Esto significa que si llama a nuevo para asignar un objeto dentro de una biblioteca compartida, debe llamar a eliminar dentro de la misma biblioteca o pueden suceder cosas extrañas.

+1

Ese problema ha sido resuelto. Esto fue cierto para el desarrollo anterior en Windows, con el desarrollo moderno ya no es un problema válido. Solo asegúrese de vincular toda la DLL a la versión compartida del tiempo de ejecución. –

+0

Gracias, no sabía que hubiera cambiado. Los problemas que tuve hace bastante poco fueron dos instancias de la biblioteca de tiempo de ejecución estática que no se comparte entre el ejecutable y el dll. – Laserallan

0

La biblioteca compartida tiene el mismo espacio de direcciones que su proceso de host. Tiene que ser de esa manera, o de lo contrario no sería capaz de pasar punteros de un módulo a otro, ya que no podrían desreferenciarlos.

Pero aunque están en el mismo espacio de direcciones, eso no significa que todos usen el mismo administrador de memoria. La consecuencia es que si proporciona una función que asigna memoria en nombre de la persona que llama, debe proporcionar una función correspondiente para liberar esa memoria, por ejemplo, libXXX_destroy().

+0

¿Podría explicarnos más sobre esto del administrador de memoria? – nick2k3

+1

El administrador de memoria es lo que parece asignarle memoria dinámicamente cuando hace cosas como malloc() o ahora. Esto solo está relacionado con el problema del espacio de direcciones de la biblioteca, ya que puede usar diferentes administradores dentro del mismo archivo fuente .c o .cpp, independientemente de en diferentes bibliotecas. –

+0

@Neil. Creo que el autor se está refiriendo al problema cuando cada archivo DLL estaba vinculado estáticamente a la biblioteca de tiempo de ejecución. Esto dio como resultado que cada DLL básicamente hiciera su propia administración de memoria (por lo tanto, una DLL no podría desasignar la memoria asignada por otra DLL). Este problema se solucionó durante mucho tiempo con el uso de una DLL compartida para las bibliotecas de tiempo de ejecución. –

2

A menos que se especifique lo contrario, una biblioteca compartida compartirá memoria con el proceso que la aloja. Cada instancia de proceso tendrá su propia copia.

Sin embargo, en Windows es posible crear variables compartidas que permitan la comunicación entre procesos. Lo haces poniéndolos en el tipo correcto de segmento. De forma predeterminada, Windows utiliza dos tipos de segmentos: los segmentos de datos son de lectura/escritura no compartida, mientras que los segmentos de código son de solo lectura ejecutables y compartidos. Sin embargo, los atributos de lectura y escritura y compartidos son ortogonales. Un segmento compartido de lectura y escritura en una biblioteca se puede usar para almacenar variables compartidas, y sobrevivirá hasta que finalice el último proceso.

Tenga cuidado con C++, ya que ejecutará felizmente constructores y destructores en la salida de inicio de proceso &, incluso si coloca variables en segmentos compartidos.

Para más detalles, vea Peering Inside the PE: A Tour of the Win32 Portable Executable File Format part 2 por Matt Pietrek.

+0

Esto está más allá del alcance de C++ (está tomando sobre violín en el nivel de ensamblaje). Hay buenas razones para NO hacer esto (específicamente por qué no están incluidas como construcciones de lenguaje). Use el sistema operativo para proporcionar instalaciones de comunicación entre procesos. Está ahí para hacer que esas cosas sean seguras. –

+0

Las bibliotecas compartidas, de las cuales se trata la pregunta, están más allá del alcance de C++, al igual que IPC. C++ solo tiene un enlace externo o interno, no tiene noción de múltiples programas que se ejecutan simultáneamente, excepto posiblemente como se relaciona con las señales. –

+0

@Martin York: Bueno, si estás tratando de entender un programa existente (y la pregunta se puede leer para sugerir eso), tienes que enfrentar la posibilidad de que el autor anterior en verdad violó de esta manera. Se equivoca en cuanto a la razón por la cual no están incluidos en el idioma, es porque estos trucos son inherentemente específicos de la plataforma y ISO C++ no. – MSalters

0

Es cierto que una biblioteca utilizará memoria en cada proceso que la cargue.Sin embargo, al menos en Windows, cuando varios procesos cargan la misma DLL, las páginas no modificadas (incluidas todas las páginas de códigos) se comparten silenciosamente bajo las cubiertas. Además, no ocupan espacio en el archivo de intercambio, ya que están respaldados por el archivo original.

Creo que esto es más complicado para .NET, debido a la compilación JIT, pero seguiría siendo cierto para los ensambles NGENed.

edición

Este es un detalle de la máquina virtual. Sin embargo, también puede flag un segmento en una DLL para compartir en todos los procesos.

Cuestiones relacionadas