Este es un seguimiento de la compilación de Dynamic Shared Library con g ++ .
Estoy tratando de crear una biblioteca de clase compartida en C ++ en Linux. Puedo hacer que la biblioteca se compile, y puedo llamar a algunas de las funciones (que no son de clase) usando los tutoriales que encontré aquí y aquí . Mis problemas comienzan cuando trato de usar las clases que están definidas en la biblioteca. El segundo tutorial al que me vinculé muestra cómo cargar los símbolos para crear objetos de las clases definidas en la biblioteca, pero no utiliza esos objetos para realizar ningún trabajo.
¿Alguien sabe de un tutorial más completo para crear bibliotecas de clases compartidas de C ++ que también muestre cómo usar esas clases en un ejecutable separado? Un tutorial muy simple que muestra la creación, el uso de objetos (los captadores y establecedores simples estarían bien), y la eliminación sería fantástica. Un enlace o una referencia a algún código fuente abierto que ilustre el uso de una biblioteca de clase compartida sería igualmente bueno.
Aunque las respuestas de codelogic y nimrodm funcionan, solo quería agregar que recogí una copia de Beginning Linux Programming desde que hice esta pregunta, y su primer capítulo tiene un código de ejemplo C y buenas explicaciones para crear y usar bibliotecas estáticas y compartidas . Estos ejemplos están disponibles a través de la Búsqueda de libros de Google en una edición anterior de ese libro .
fuente
Respuestas:
myclass.h
myclass.cc
class_user.cc
En Mac OS X, compile con:
En Linux, compile con:
Si esto fuera para un sistema de complemento, usaría MyClass como clase base y definiría todas las funciones virtuales requeridas. El autor del complemento derivaría de MyClass, anularía los virtuales e implementaría
create_object
ydestroy_object
. Su aplicación principal no necesitaría ser cambiada de ninguna manera.fuente
extern "C"
porque ladlsym
función es una función C. Y para cargar dinámicamente lacreate_object
función, utilizará la vinculación de estilo C. Si no usara elextern "C"
, no habría forma de saber el nombre de lacreate_object
función en el archivo .so, debido a la alteración del nombre en el compilador de C ++.A continuación se muestra un ejemplo de una biblioteca de clase compartida compartida. [H, cpp] y un módulo main.cpp que usa la biblioteca. Es un ejemplo muy simple y el archivo MAKE podría mejorarse mucho. Pero funciona y puede ayudarte:
shared.h define la clase:
shared.cpp define las funciones getx / setx:
main.cpp usa la clase,
y el archivo MAKE que genera libshared.so y enlaza main con la biblioteca compartida:
Para ejecutar 'main' y vincular con libshared.so probablemente necesitará especificar la ruta de carga (o ponerla en / usr / local / lib o similar).
A continuación se especifica el directorio actual como la ruta de búsqueda para bibliotecas y se ejecuta main (sintaxis bash):
Para ver que el programa está vinculado con libshared.so puede probar ldd:
Impresiones en mi máquina:
fuente
-L. -lshared -Wl,-rpath=$$(ORIGIN)
al vincular y soltar esoLD_LIBRARY_PATH=.
.Básicamente, debe incluir el archivo de encabezado de la clase en el código donde desea usar la clase en la biblioteca compartida. Luego, cuando enlace, use la bandera '-l' para vincular su código con la biblioteca compartida. Por supuesto, esto requiere que .so esté donde el sistema operativo pueda encontrarlo. Ver 3.5. Instalación y uso de una biblioteca compartida
El uso de dlsym es para cuando no sabe en tiempo de compilación qué biblioteca desea usar. Eso no parece ser el caso aquí. ¿Quizás la confusión es que Windows llama a las bibliotecas cargadas dinámicamente si hace el enlace en la compilación o en tiempo de ejecución (con métodos análogos)? Si es así, puede pensar en dlsym como el equivalente de LoadLibrary.
Si realmente necesita cargar dinámicamente las bibliotecas (es decir, son complementos), estas preguntas frecuentes deberían ser útiles.
fuente
Además de las respuestas anteriores, me gustaría crear conciencia sobre el hecho de que debe usar el lenguaje RAII (La adquisición de recursos es la inicialización) para estar seguro sobre la destrucción del controlador.
Aquí hay un ejemplo de trabajo completo:
Declaración de interfaz
Interface.hpp
:Contenido de la biblioteca compartida:
Controlador dinámico de biblioteca compartida
Derived_factory.hpp
::Codigo del cliente:
Nota:
.hpp
y.cpp
archivos.new
/delete
sobrecarga.Dos artículos claros para obtener más detalles:
fuente