ejecutar compilar compilador como c++ linux shared-libraries

c++ - compilar - gcc linux



Biblioteca compartida dinĂ¡mica de C++ en Linux (3)

A continuación, se muestra un ejemplo de una biblioteca de clases compartida compartida. [H, cpp] y un módulo main.cpp que utiliza la biblioteca. Es un ejemplo muy simple y el archivo MAKE podría mejorar mucho. Pero funciona y puede ayudarte:

shared.h define la clase:

class myclass { int myx; public: myclass() { myx=0; } void setx(int newx); int getx(); };

shared.cpp define las funciones getx / setx:

#include "shared.h" void myclass::setx(int newx) { myx = newx; } int myclass::getx() { return myx; }

main.cpp usa la clase,

#include <iostream> #include "shared.h" using namespace std; int main(int argc, char *argv[]) { myclass m; cout << m.getx() << endl; m.setx(10); cout << m.getx() << endl; }

y el archivo MAKE que genera libshared.so y enlaces principales con la biblioteca compartida:

main: libshared.so main.o $(CXX) -o main main.o -L. -lshared libshared.so: shared.cpp $(CXX) -fPIC -c shared.cpp -o shared.o $(CXX) -shared -Wl,-soname,libshared.so -o libshared.so shared.o clean: $rm *.o *.so

Para ejecutar ''main'' y vincularse con libshared.so probablemente necesite 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 ejecuta main (sintaxis bash):

export LD_LIBRARY_PATH=. ./main

Para ver que el programa está vinculado con libshared.so puedes probar ldd:

LD_LIBRARY_PATH=. ldd main

Imprime en mi máquina:

~/prj/test/shared$ LD_LIBRARY_PATH=. ldd main linux-gate.so.1 => (0xb7f88000) libshared.so => ./libshared.so (0xb7f85000) libstdc++.so.6 => /usr/lib/libstdc++.so.6 (0xb7e74000) libm.so.6 => /lib/libm.so.6 (0xb7e4e000) libgcc_s.so.1 => /usr/lib/libgcc_s.so.1 (0xb7e41000) libc.so.6 => /lib/libc.so.6 (0xb7cfa000) /lib/ld-linux.so.2 (0xb7f89000)

Esta es una continuación de la compilación de Dynamic Shared Library con g ++ .

Intento crear una biblioteca de clases compartida en C ++ en Linux. Puedo hacer que la biblioteca compile y puedo llamar a algunas de las funciones (que no son de clase) usando los tutoriales que encontré here y here . Mis problemas comienzan cuando trato de usar las clases que están definidas en la biblioteca. El segundo tutorial al que me he vinculado muestra cómo cargar los símbolos para crear objetos de las clases definidas en la biblioteca, pero no llega a usar esos objetos para realizar cualquier trabajo.

¿Alguien sabe de un tutorial más completo para crear bibliotecas de clases C ++ compartidas que también muestra cómo usar esas clases en un ejecutable separado? Un tutorial muy simple que muestra creación de objetos, uso (getters y setters 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 clases compartida sería igualmente bueno.

Aunque las respuestas de codelogic y here sí funcionan, solo quería agregar que recogí una copia de here desde que hice esta pregunta, y su primer capítulo tiene código C de ejemplo 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 .


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 se vincule, use el indicador ''-l'' para vincular su código con la biblioteca compartida. Por supuesto, esto requiere que el .so esté donde el SO puede encontrarlo. Ver 3.5. Instalación y uso de una biblioteca compartida

Usar dlsym es para cuando no sabe en tiempo de compilación qué biblioteca quiere usar. Eso no suena como si fuera el caso aquí. Tal vez la confusión es que Windows llama a las bibliotecas cargadas dinámicamente ya sea que realice el enlace en compilación o en tiempo de ejecución (con métodos análogos). Si es así, entonces puedes pensar en dlsym como el equivalente de LoadLibrary.

Si realmente necesita cargar dinámicamente las bibliotecas (es decir, son complementos), entonces estas preguntas frecuentes deberían ser útiles.


myclass.h

#ifndef __MYCLASS_H__ #define __MYCLASS_H__ class MyClass { public: MyClass(); /* use virtual otherwise linker will try to perform static linkage */ virtual void DoSomething(); private: int x; }; #endif

myclass.cc

#include "myclass.h" #include <iostream> using namespace std; extern "C" MyClass* create_object() { return new MyClass; } extern "C" void destroy_object( MyClass* object ) { delete object; } MyClass::MyClass() { x = 20; } void MyClass::DoSomething() { cout<<x<<endl; }

class_user.cc

#include <dlfcn.h> #include <iostream> #include "myclass.h" using namespace std; int main(int argc, char **argv) { /* on Linux, use "./myclass.so" */ void* handle = dlopen("myclass.so", RTLD_LAZY); MyClass* (*create)(); void (*destroy)(MyClass*); create = (MyClass* (*)())dlsym(handle, "create_object"); destroy = (void (*)(MyClass*))dlsym(handle, "destroy_object"); MyClass* myClass = (MyClass*)create(); myClass->DoSomething(); destroy( myClass ); }

En Mac OS X, compila con:

g++ -dynamiclib -flat_namespace myclass.cc -o myclass.so g++ class_user.cc -o class_user

En Linux, compila con:

g++ -fPIC -shared myclass.cc -o myclass.so g++ class_user.cc -ldl -o class_user

Si esto fuera por un sistema de complemento, usaría MyClass como una clase base y definiría todas las funciones requeridas virtuales. El autor del complemento derivaría entonces de MyClass, anularía los virtuales e implementaría create_object y destroy_object . No es necesario cambiar su aplicación principal de ninguna manera.