Pregunta

EDITAR: Supongo que debo aclarar, en caso de que importe. Estoy en un cuadro de AIX Unix, así que estoy usando compiladores VAC, no compiladores GNU. Finalizar edición


Estoy bastante oxidado en C / C ++, así que perdóname si esta es una pregunta simple.

Me gustaría quitar funciones comunes de algunos de mis programas de C y ponerlas en bibliotecas compartidas u objetos compartidos. Si estuviera haciendo esto en perl, pondría mis subs en un módulo perl y utilizaría ese módulo cuando fuera necesario.

Por un ejemplo, digamos que tengo esta función:

int giveInteger()
{
    return 1034;
}

Obviamente, este no es un ejemplo del mundo real, pero si quisiera compartir esa función, ¿cómo procedería?

Estoy bastante seguro de que tengo 2 opciones:

  1. Poner mi función compartida en un archivo y hacer que se compile con mi programa principal en tiempo de compilación. Si alguna vez hago cambios en mi función compartida, tendría que volver a compilar mi programa principal.
  2. Poner mi función compartida en un archivo y compilarla como una biblioteca compartida (si tengo los términos correctos), y tengo el enlace de mi programa principal a esa biblioteca compartida. Cualquier cambio que realice en mi biblioteca compartida (después de compilarlo) se integrará en mi programa principal en tiempo de ejecución sin volver a compilar mi programa principal.

¿Estoy en lo cierto al pensar?

Si es así, ¿cómo puedo cumplir con cualquiera de estos dos métodos? He buscado mucho y parece que encuentro información sobre cómo podría tener mi propio enlace de programa a la biblioteca compartida de otra persona, pero no cómo crear mis propias funciones compartidas y compilarlas de una manera que pueda usarlas en mi propio programa. .

Muchas gracias!

Brian


EDITAR:

Conclusión

¡Gracias a todos por su ayuda! Pensé que agregaría a esta publicación lo que me funciona (para bibliotecas compartidas dinámicas en AIX) para que otros puedan beneficiarse:

Compilo mis funciones compartidas:

xlc -c sharedFunctions.c -o sharedFunctions.o

Luego conviértelo en un objeto compartido:

xlc -qmkshrobj -qexpfile=exportlist sharedFunctions.o
xlc -G -o libsharedFunctions.so sharedFunctions.o  -bE:exportlist

Luego enlaza otro programa:

xlc -brtl -o mainProgram mainProgram.c  -L. -lsharedFunctions

Y otro comentario me ayudó a encontrar este enlace, que también ayudó: http: //publib.boulder.ibm.com/infocenter/comphelp/v7v91/topic/com.ibm.vacpp7a.doc/proguide/ref/compile_library.htm

Gracias de nuevo a todos los que me ayudaron!

¿Fue útil?

Solución

Sí, tienes razón. El primero se denomina biblioteca estática , mientras que el segundo se denomina biblioteca compartida , porque el código no está vinculado al ejecutable en el momento de la compilación, sino cada vez más cuando su programa está cargado.

Biblioteca estática

Compile el código de su biblioteca de la siguiente manera:

gcc -c *.c

El -c le dice al programa que no vincule el archivo objeto, pero solo lo deja con los archivos objeto para cada archivo .c que se compiló. Ahora, archívalos en una biblioteca estática:

ar rcs libmystuff.a *.o 

man ar le dirá lo que significan las opciones de rcs. Ahora, libmystuff.a es un archivo un rchive (puede abrirlo con algunos visores de archivos zip) que contienen esos archivos de objetos, junto con un índice de símbolos para cada archivo de objetos. Puedes vincularlo a tu programa:

gcc *.c libmystuff.a -o myprogram

Ahora, tu programa está listo. Tenga en cuenta que el orden en el que aparecen las bibliotecas estáticas en el comando es importante. Consulte mi orden de enlaces .

Biblioteca compartida

Para una biblioteca compartida, creará su biblioteca con

gcc -shared -o libmystuff.so *.c

Eso es todo lo que se necesita, libmystuff.so ahora es un archivo bject s ared o . Si desea vincular un programa a él, debe colocarlo en un directorio que esté listado en el archivo /etc/ld.so.conf , o que esté dado por el - L cambia a GCC, o aparece en la variable LD_LIBRARY_PATH. Al vincular, debes cortar el prefijo lib y el sufijo .so del nombre de la biblioteca que le dices a gcc.

gcc -L. -lmystuff *.c -o myprogram

Internamente, gcc solo pasará tus argumentos al enlazador GNU. Puede ver qué argumentos pasa usando la opción - ### : Gcc imprimirá los argumentos exactos dados a cada subproceso.

Para obtener detalles sobre el proceso de vinculación (cómo se hacen algunas cosas internamente), vea mi enlazador GCC de Linux respuesta.

Otros consejos

Tienes una tercera opción. En general, su compilador de C ++ debería poder vincular rutinas de C. Las opciones necesarias pueden variar de compilador a compilador, por lo que R es su M fina, pero básicamente, debería poder compilar con g ++ como aquí:

$ g++ -o myapp myapp.cpp myfunc.c giveint.c

... o compilar por separado

$ gcc -c myfunc.c
$ gcc -c giveint.c
$ g++ -c myapp.cpp
$ g++ -o myapp myapp.o myfunc.o

También debe incluir su declaración de las funciones; lo haces en C ++ como

extern "C" {
    int myfunc(int,int);
    int giveInterger(void);
}

Es necesario distinguir entre recompilar y volver a vincular.

Si coloca giveInteger () en una biblioteca separada (archivada) y luego la modifica más tarde, (obviamente) deberá volver a compilar el archivo fuente en el que está definido, y < em> relink todos los programas que lo utilizan; pero no necesitará recompilar tales programas [1].

Para una biblioteca compartida, deberá recompilar y volver a vincular la biblioteca; pero no tendrá que volver a vincular o recompilar ninguno de los programas que lo utilizan.

La construcción de bibliotecas compartidas de C ++ en AIX solía ser complicada; necesitabas usar el script shell de makeC ++ SharedLib. Pero con VAC 5.0 y 6.0 se hizo bastante fácil. Creo que todo lo que necesitas hacer es [2]:

xlC -G -o shr.o giveInteger.cc
xlC -o myapp main.cc shr.o

[1] Si escribes un Makefile correcto (que es una práctica recomendada), todo esto sucederá automáticamente cuando escribas make .

[2] Hay una cierta característica de AIX que puede complicar las cosas: de forma predeterminada, las bibliotecas compartidas se cargan en la memoria, y " pegar " allí hasta el posterior reinicio. Así que puedes reconstruir el shr.o, volver a ejecutar el programa y observar " antiguo " Versión de la biblioteca en ejecución. Para evitar esto, una práctica común es hacer que shr.o sea ilegible en el mundo:

chmod 0750 shr.o
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top