2009-12-19 11 views
7

Estoy manteniendo un small application que tiene alguna funcionalidad tipo complemento, que se implementa a través de módulos dinámicos cargados en tiempo de ejecución.Acceso a las variables globales del programa principal desde una biblioteca dinámica dlopen() ed en C en OS X

Específicamente, dado que es una aplicación Gtk +, estoy usando gmodule, pero la pregunta se aplica también a la biblioteca dinámica basada en dlfcn.h/dlopen().

Mi programa principal tiene una única variable de estructura global que contiene algo de información global. Quiero que esta información esté disponible para las funciones definidas en los complementos cargados dinámicamente.

En Linux, podría referirme directamente a esta variable global; esto funciona bien, y supongo que gcc o el vinculador se encargan de exportar las variables globales desde el programa principal a las bibliotecas dinámicas.

El problema es que esto no funciona en Mac OS X. ¿Hay alguna forma de hacerlo en OS X?

De lo contrario, ¿existe una forma más "óptima" de exponer la información global a las bibliotecas cargadas dinámicamente?

+0

BTW aquí hay un código de ejemplo que simplifica el problema: http://pastie.org/749794 – shevron

Respuesta

10

Coloque el mundial en main.c y os lo externo en el objeto compartido, y probar este:

MACOSX_DEPLOYMENT_TARGET=10.3 ld -dylib -undefined dynamic_lookup -o multiply.so multiply.o 

o

MACOSX_DEPLOYMENT_TARGET=10.3 libtool -dynamic -undefined dynamic_lookup -o multiply.so multiply.o 

Funcionó para mí en Mac OS X 10.4

+0

Gracias, esto funciona! Aunque no utilicé el entorno TAGET var, supongo que está menos relacionado. ¡Ahora para ver cómo integrar esto en mis Makefiles! – shevron

+0

También funciona el directorio de gcc: gcc -Wall -g -fPIC -c multiply.c gcc -shared -Wl, -undefinido, dynamic_lookup -o multiplicaly.so multiple.o – shevron

3

Dado que se declara

int global; 

en la cabecera multiply.h, el archivo DLL y programa principal tanto tienen su propia copia de la misma. En su lugar, declarar la global en main.c

int global; 

y en multiply.c lo declaran como extern:

extern int global; 

Ahora si se vincula con la opción main.cpp -rdynamic, entonces símbolos del ejecutables se exportará a la DLL.

Probé esto en Linux y funcionó, pero me temo que no tengo acceso para probar en MacOS. Como tu código de muestra tampoco funcionó en Linux, espero que este sea el problema.

+0

AFAIK -rdynamic no es compatible con OS X. En cualquier caso, recibí un error acerca de que "_global" estaba indefinido cuando intentaba vincular multiply.o – shevron

Cuestiones relacionadas