2011-12-24 15 views
8

Por ejemplo, si I declarar una función en la aplicación principal, y un pase de un puntero a la misma, a partir de una biblioteca cargada dinámicamente (a través de dlopen bajo Linux o LoadLibrary bajo Windows) utilizando un argumento símbolo recibido (a través de dlsym o GetProcAddress respectivamente) y tratar de llamar a esa función, ¿funcionaría correctamente?¿El puntero C/C++ guarda la dirección de memoria absoluta, o relativa a la aplicación, o relativa al módulo?

¿Lo mismo si pasa el puntero desde una biblioteca cargada dinámicamente a otra? Creo que debería funcionar si el puntero al menos en relación con la aplicación, pero no en relación con el módulo/biblioteca.

Otro ejemplo. Declaro una función en una aplicación y le paso el puntero a otra aplicación completamente independiente (tanto C como C++) de alguna manera (cadena de parámetros o archivo i/o - identifique cómo, solo una idea) y trato de llamar a esta función, ¿podría? trabajar tambien? Podría esperar que funcione si los indicadores son absolutos. Tal vez simplemente no funcionará porque al sistema no le gustará esa llamada cruzada debido a la seguridad.

+1

¿Importa de alguna manera a su programa? –

+0

Bueno, el intercambio entre procesos no tiene importancia para mi programa, solo generaliza la pregunta. Compartir en bibliotecas dinámicas y cargadas estáticamente en mi programa es lo que necesito, porque el plugin puede llamar a las funciones de la aplicación principal indirectamente, a través de la dirección. – Nick

+0

Quizás podría ser otra pregunta ... Tengo una aplicación principal, una biblioteca principal (vinculada) y un complemento para cargar dinámicamente. La aplicación principal registra una matriz de objetos, que contiene direcciones de funciones en algunos campos (tipo declarado en el encabezado de la biblioteca, definido en la fuente de la biblioteca). El complemento incluye el encabezado de la biblioteca, pero no registra nada, solo toma esos objetos y ejecuta las funciones en las direcciones declaradas en el encabezado de la biblioteca. Lo he probado, funciona, espero que no haya problemas si el espacio de direcciones es el mismo para todo el proceso en todas las plataformas. – Nick

Respuesta

7

Primero debe comprender que en C y C++ no es necesario que el valor de un puntero esté relacionado con las direcciones realmente utilizadas, siempre que la aritmética del puntero funcione con él, el puntero nulo tenga un valor R de 0 y el la implementación logra hacer un mapa bijectively entre punteros de máquina y punteros abstractos de lenguaje.

En los procesos de sistemas modernos, vea un espacio de direcciones virtual y cada proceso tiene su propio espacio de direcciones. Las bibliotecas pueden cargarse en cualquier dirección, por lo que pasar un puntero entre procesos es una completa tontería, al menos en las arquitecturas de memoria paginada. Sin embargo, dentro de un proceso, los indicadores de nivel de la máquina se pasan entre bibliotecas cargadas sin problema; después de todo, comparten el mismo espacio de direcciones. En el nivel del idioma, es posible que no sean iguales (aunque suelen serlo), si entran en contacto varios idiomas. Pero las unidades de compilación creadas utilizando el mismo compilador usarán la misma semántica de puntero. Además, la mayoría de las implementaciones de lenguaje que se dirigen a la máquina nativa concuerdan con la semántica del puntero por la sencilla razón de que tener que convertir entre formatos de puntero crearía un gran golpe de rendimiento.

+0

Pero ... ¿qué pasa si la biblioteca principal de la aplicación y compilación de biblioteca compartida utilizando un compilador diferente, tanto C++ como diferentes fabricantes o versiones? ¿Sería correcto llamar a una función de biblioteca de otra biblioteca? – Nick

+2

@Nick: normalmente lo hará, porque los sistemas operativos y las arquitecturas definen una llamada "ABI", es decir, las interfaces binarias entre los procesos y el sistema operativo. Esas ABI definen cómo se llaman las funciones en el nivel de la máquina, cómo se hacen las llamadas al sistema operativo, etc. Y debido a que los programadores son flojos, eso incluye a los programadores de compiladores, y debido a que tiene más sentido, todos los compiladores que se dirijan a una plataforma específica acordarán la ABI. Pero tenga en cuenta que esto es una cuestión de plataforma, no de lenguaje. – datenwolf

+0

@datewolf: eso está bien, gracias. – Nick

5

Las cosas funcionan de manera diferente en los diferentes sistemas operativos. En sistemas operativos antiguos/integrados, todos los procesos comparten el mismo espacio: un proceso puede ensuciar las cosas para otro.

En la mayoría de los sistemas operativos modernos de uso general (es decir, no incrustados) cada proceso tiene un espacio de direcciones separado. Todas las direcciones son relativas a este espacio. No importa cómo se compilan/vinculan las cosas juntas, si están en el mismo proceso , comparten el espacio de direcciones.

De ello se deduce que dos procesos distintos no tienen formas implícitas de acceder al espacio de los demás.

4

Es debido a MMU. Es unidad de hardware en la mayoría de los procesadores para proteger aplicaciones entre sí. Su objetivo principal es proteger kernel/OS de la aplicación. Cada aplicación o proceso tiene su propia memoria y no puede acceder a la memoria de otro proceso, pero tiene que pasar por kernel/OS de alguna manera.

+2

No recibí la observación de win95. – avakar

+0

@avakar Win95 cargó archivos DLL en la memoria que se compartió entre todos los procesos: un proceso deshonesto o defectuoso podría arruinar todo el sistema. – snemarch

+0

@snemarch, todas las versiones de Windows hacen eso, pero las páginas no se pueden escribir. Demonios, espero que Linux también lo haga; sería un desperdicio guardar múltiples copias de la misma información. – avakar

7

Es absoluto.

El hecho de que se trata de una dirección virtual de no tiene nada que ver con esto - es un absoluto dirección virtual . Hace ninguna diferencia a su programa si está utilizando la memoria virtual o la memoria física ...no debe preocuparse por esto a menos que esté pasando los punteros entre los procesos (que dudo que sea), o a menos que esté escribiendo código de kernel de bajo nivel o mapeando/quitando páginas manualmente (lo que también dudo de usted son).

Cuestiones relacionadas