2010-07-01 10 views
5

Mi primera publicación en este sitio con gran esperanza :: Estoy tratando de comprender enlaces estáticos, enlaces dinámicos, bibliotecas compartidas, bibliotecas estáticas, etc., con gcc. Cada vez que trato de profundizar en este tema, tengo algo que no entiendo del todo.en gcc cómo forzar la resolución del símbolo en el tiempo de ejecución

manos a la obra:

bash$ cat main.c 

#include "printhello.h" 
#include "printbye.h" 

void main() 
{ 
PrintHello(); 
PrintBye(); 
} 

bash$ cat printhello.h 
void PrintHello(); 

bash$ cat printbye.h 
void PrintBye(); 

bash$ cat printbye.c 
#include <stdio.h> 

void PrintBye() 
{ 
printf("Bye bye\n"); 
} 

bash$ cat printhello.c 
#include <stdio.h> 

void PrintHello() 
{ 
printf("Hello World\n"); 
} 

gcc -Wall -fPIC -c *.c -I. 
gcc -shared -Wl,-soname,libcgreet.so.1 -o libcgreet.so.1.0 *.o 
ln -sf libcgreet.so.1.0 libcgreet.so 
ln -sf libcgreet.so.1.0 libcgreet.so.1 

Así que han creado una biblioteca compartida. Ahora quiero vincular esta biblioteca compartida con mi programa principal para crear un ejecutable.

gcc -Wall -L. main.c -lcgreet -o greet

Se trabaja muy bien y si fijo LD_LIBRARY_PATH antes de ejecutar saludar (o vincularlo con la opción rpath) que puede hacer que funcione.

Mi pregunta es sin embargo diferente: Desde que estoy de todos modos usando la biblioteca compartida, no es posible forzar resolución símbolo en tiempo de ejecución (no estoy seguro acerca de la terminología, pero tal vez llamada la vinculación dinámica según el libro "enlazadores y Cargadores") . Entiendo que es posible que no deseemos hacerlo, ya que esto hace que el programa se ejecute lentamente y tiene una sobrecarga cada vez que queremos ejecutar el programa, pero estoy tratando de entender esto para borrar mis conceptos.

¿Se enlazador gcc proporciona ninguna opción de retrasar resolución símbolo en tiempo de ejecución? (Hacerlo con la biblioteca vamos realmente a ejecutar el programa con) (como biblioteca disponible en tiempo de compilación puede ser diferente de la que está disponible en tiempo de ejecución si cualquier cambio en la biblioteca) yo quiero ser capaz de hacer algo como :

bash $ gcc -I main.c. (¿qué opción necesita aquí?) para no tener que dar el nombre de la biblioteca, y solo decirle que quiero hacer la resolución del símbolo en tiempo de ejecución, por lo que los encabezados son lo suficientemente buenos no son necesarios

Gracias, aprendizaje para siempre.

+0

http://www.yolinux.com/TUTORIALS/LibraryArchives-StaticAndDynamic.html – adf88

+0

Asegúrese de etiquetar la pregunta con el lenguaje apropiado. Está etiquetado como C++, pero el código es C. Tenga en cuenta que para poder usar la biblioteca dinámica pura, la carga del código en C++ tendrá que contener un exceso de "extern" C "rociado que no es necesario ni válido en C. –

Respuesta

9

Cualquier enlazador (gcc, ld o cualquier otro) solo resuelve enlaces en tiempo de compilación. Esto se debe a que el estándar ELF (como la mayoría de los demás) no define el enlace "en tiempo de ejecución" como usted describe. O bien se vinculan estáticamente (es decir, lib.a) o en el momento del inicio (lib.so, que debe estar presente cuando se carga el ELF). Sin embargo, si utiliza un enlace dinámico, el vinculador solo incluirá en el ELF el nombre del archivo y los símbolos que debe encontrar, no vincula el archivo directamente. Por lo tanto, si desea actualizar la lib a una versión más reciente más adelante, puede hacerlo, siempre que el sistema pueda encontrar el mismo nombre de archivo (la ruta puede ser realmente diferente) y los mismos nombres de símbolos.

La otra opción, para obtener símbolos en tiempo de ejecución, es usar dlopen, que no tiene nada que ver con gcc o ld. dlopen en pocas palabras, abre una biblioteca de vínculos dinámicos, como fopen podría, y le devuelve un identificador, que luego pasa a dlsym con el nombre del símbolo que desea, que podría ser un nombre de función, por ejemplo. dlsym le pasará un puntero a ese símbolo, que luego puede usar para llamar a la función o usarla como una variable. Así es como se implementan los complementos.

+0

+1 para una buena respuesta y señalar complementos. – stinky472

+1

En caso de que la etiqueta del lenguaje C++ sea correcta, recuerde marcar los símbolos como 'extern' C "' para que no se alteren en tiempo de compilación. –

1

Creo que está buscando la opción ld '--unresolved-symbols = ignore-all', sí, puede hacerlo (ignore la respuesta anterior).Imagine el escenario en el que una biblioteca compartida se cargó tarde (cuando el programa ya se está ejecutando), puede usar todos los símbolos que ya están resueltos/cargados por el proceso principal, sin necesidad de molestarse en volver a hacerlo. Por cierto, no lo hace innecesariamente, lo hace lento, al menos en Linux

Cuestiones relacionadas