visual variable son que locales las globales externas estaticas ejemplos declaracion automatica c++ linker global-variables global dynamic-linking

c++ - son - ¿Qué sucede con las variables globales y estáticas en una biblioteca compartida cuando se vincula dinámicamente?



variables globales y locales en visual basic (1)

Esta es una diferencia bastante famosa entre Windows y los sistemas tipo Unix.

No importa qué:

  • Cada proceso tiene su propio espacio de direcciones, lo que significa que nunca hay memoria compartida entre los procesos (a menos que utilice alguna biblioteca o extensiones de comunicación entre procesos).
  • La regla de una definición (ODR) sigue siendo válida, lo que significa que solo puede tener una definición de la variable global visible en tiempo de enlace (enlace estático o dinámico).

Entonces, la cuestión clave aquí es realmente la visibilidad .

En todos los casos, las variables globales static (o funciones) nunca son visibles desde fuera de un módulo (dll / so o ejecutable). El estándar de C ++ requiere que estos tengan un enlace interno, lo que significa que no son visibles fuera de la unidad de traducción (que se convierte en un archivo de objeto) en el que están definidos. Entonces, eso resuelve ese problema.

Donde se complica es cuando tienes variables globales extern . Aquí, los sistemas Windows y Unix son completamente diferentes.

En el caso de Windows (.exe y .dll), las variables globales extern no son parte de los símbolos exportados. En otras palabras, los diferentes módulos no son conscientes de las variables globales definidas en otros módulos. Esto significa que obtendrá errores de enlazador si intenta, por ejemplo, crear un ejecutable que se supone que usa una variable extern definida en una DLL, porque esto no está permitido. Debería proporcionar un archivo de objeto (o biblioteca estática) con una definición de esa variable extern y vincularlo estáticamente con el archivo ejecutable y el archivo DLL, lo que da como resultado dos variables globales distintas (una que pertenece al archivo ejecutable y otra que pertenece a la DLL )

Para exportar realmente una variable global en Windows, debe usar una sintaxis similar a la función exportar / importar sintaxis, es decir:

#ifdef COMPILING_THE_DLL #define MY_DLL_EXPORT extern "C" __declspec(dllexport) #else #define MY_DLL_EXPORT extern "C" __declspec(dllimport) #endif MY_DLL_EXPORT int my_global;

Cuando haces eso, la variable global se agrega a la lista de símbolos exportados y se puede vincular como todas las otras funciones.

En el caso de entornos tipo Unix (como Linux), las bibliotecas dinámicas, llamadas "objetos compartidos" con extensión .so exportan todas las variables (o funciones) extern globales. En este caso, si realiza un enlace de tiempo de carga desde cualquier lugar a un archivo de objeto compartido, entonces las variables globales se comparten, es decir, se unen entre sí. Básicamente, los sistemas tipo Unix están diseñados para que prácticamente no haya diferencia entre vincularse con una biblioteca estática o dinámica. De nuevo, la ODR se aplica en todos los ámbitos: una variable global extern se compartirá entre los módulos, lo que significa que solo debe tener una definición en todos los módulos cargados.

Finalmente, en ambos casos, para sistemas Windows o Unix, puede hacer un enlace en tiempo de ejecución de la biblioteca dinámica, es decir, utilizando LoadLibrary() / GetProcAddress() / FreeLibrary() o dlopen() / dlsym() / dlclose() . En ese caso, debe obtener manualmente un puntero a cada uno de los símbolos que desea usar, y eso incluye las variables globales que desea usar. Para las variables globales, puede usar GetProcAddress() o dlsym() del mismo modo que para las funciones, siempre que las variables globales sean parte de la lista de símbolos exportada (según las reglas de los párrafos anteriores).

Y, por supuesto, como nota final necesaria: se deben evitar las variables globales . Y creo que el texto que citó (sobre las cosas "poco claras") se refiere exactamente a las diferencias específicas de la plataforma que acabo de explicar (las bibliotecas dinámicas no están realmente definidas por el estándar C ++, este es un territorio específico de la plataforma, lo que significa es mucho menos confiable / portátil).

Estoy tratando de entender qué sucede cuando los módulos con variables globales y estáticas están vinculados dinámicamente a una aplicación. Por módulos, me refiero a cada proyecto en una solución (¡trabajo mucho con Visual Studio!). Estos módulos están integrados en * .lib o * .dll o en * .exe en sí.

Entiendo que el binario de una aplicación contiene datos globales y estáticos de todas las unidades de traducción individuales (archivos de objeto) en el segmento de datos (y solo de lectura, segmento de datos si const).

  • ¿Qué sucede cuando esta aplicación utiliza un módulo A con enlaces dinámicos de tiempo de carga? Supongo que la DLL tiene una sección para sus valores globales y estáticos. ¿El sistema operativo los carga? Si es así, ¿dónde se cargan?

  • ¿Y qué sucede cuando la aplicación usa un módulo B con un enlace dinámico en tiempo de ejecución?

  • Si tengo dos módulos en mi aplicación que usan A y B, ¿se crean copias de los globales A y B como se menciona a continuación (si son procesos diferentes)?

  • ¿Las DLL A y B tienen acceso a las aplicaciones globales?

(Por favor, indique sus razones también)

Citando desde MSDN :

Las variables que se declaran como globales en un archivo de código fuente DLL son tratadas como variables globales por el compilador y el enlazador, pero cada proceso que carga una DLL determinada obtiene su propia copia de las variables globales de esa DLL. El alcance de las variables estáticas se limita al bloque en el que se declaran las variables estáticas. Como resultado, cada proceso tiene su propia instancia de las variables DLL globales y estáticas de forma predeterminada.

y desde here :

Al vincular dinámicamente módulos, puede no estar claro si las diferentes bibliotecas tienen sus propias instancias de globales o si los globales se comparten.

Gracias.