2009-07-17 14 views
15

Tengo un objeto compartido (un así - el equivalente de Linux de un dll de Windows) que me gustaría importar y usar con mi código de prueba.¿Cómo cargo un objeto compartido en C++?

Estoy seguro de que no es este sencillo;) pero este es el tipo de cosas que le gustaría hacer ..

#include "headerforClassFromBlah.h" 

int main() 
{ 
    load("blah.so"); 

    ClassFromBlah a; 
    a.DoSomething(); 
} 

que suponer que se trata de una cuestión muy básica pero no puedo encuentre cualquier cosa que salte a buscar en la web.

+0

Quizás estoy confundido pero no parece que haya suficiente información allí. ¿Qué contiene blah.so, por ejemplo? ¿Estás seguro de que no estás hablando solo de usar una referencia? – Goz

+0

¿A qué te refieres con "compartido" exactamente? – Klaim

+0

Err ... entonces los archivos no son archivos de código, ¿verdad? Tal vez quieras recuperar un objeto de a.¿archivo (biblioteca compartida)? – Klaim

Respuesta

33

Hay dos formas de objetos de carga compartida en C++

Para cualquiera de estos métodos siempre se necesitaría el archivo de cabecera para el objeto que desea utilizar. El encabezado contendrá las definiciones de las clases u objetos que quiera usar en su código.

estáticamente:

#include "blah.h" 
int main() 
{ 
    ClassFromBlah a; 
    a.DoSomething(); 
} 

gcc yourfile.cpp -lblah 

dinámicamente (en Linux):

#include <stdio.h> 
#include <stdlib.h> 
#include <dlfcn.h> 
int main(int argc, char **argv) { 
    void *handle; 
    double (*cosine)(double); 
    char *error; 
    handle = dlopen ("libm.so", RTLD_LAZY); 
    if (!handle) { 
     fprintf (stderr, "%s\n", dlerror()); 
     exit(1); 
    } 
    dlerror(); /* Clear any existing error */ 
    cosine = dlsym(handle, "cos"); 
    if ((error = dlerror()) != NULL) { 
     fprintf (stderr, "%s\n", error); 
     exit(1); 
    } 
    printf ("%f\n", (*cosine)(2.0)); 
    dlclose(handle); 
    return 0; 
} 

* Robados de dlopen Linux man page El proceso bajo las ventanas o cualquier otra plataforma es lo mismo, basta con sustituir dlopen con la versión plataformas de la búsqueda dinámica de símbolos.

Para que el método dinámico funcione, todos los símbolos que desea importar/exportar deben tener una vinculación C externa.

Hay algunas palabras Here sobre cuándo usar estática y cuándo usar el enlace dinámico.

+5

+1. Tal vez vale la pena mencionar explícitamente que dlopen es POSIX, no C o C++. En algunas plataformas no hay carga dinámica, pero todavía se están implementando en C++. –

+0

¿Cuál es el comando para construir este archivo, sería g ++ filename.cpp -L algunaIncluye -0 archivo de trabajo? –

+0

Tendrá que vincular usando también -ldl –

4

Depende de la plataforma. Para hacerlo en tiempo de ejecución, en Linux, usa dlopen, en Windows, usa LoadLibrary.

Para hacerlo en tiempo de compilación, en las ventanas se exporta el nombre de la función usando dllexport y dllimport. En Linux, gcc exporta todos los símbolos públicos, por lo que puede vincularlo normalmente y llamar a la función. En ambos casos, normalmente esto requiere que tenga el nombre del símbolo en un archivo de encabezado que luego tiene #include, luego se vincula a la biblioteca utilizando las funciones de su compilador.

3

Necesita #incluir los encabezados asociados con la biblioteca compartida para obtener las declinaciones de cosas como ClassFromBlah. A continuación, deberá enlazar con la del .so - exactamente cómo se hace esto depende de su compilador e instalación en general, pero por g ++ algo como:

g++ myfile.cpp -lblah 

probablemente va a funcionar.

+0

He incluido los encabezados y puedo compilar y vincular mi código con el objeto compartido, pero no tengo ni idea de cómo usarlo y las clases que contiene. No lo dejé claro, vea mi actualización al fragmento de código. ¿Alguna idea? –

+1

En cuanto a cómo usar las clases que contiene, tienes que RTFM, me temo. –

+0

@neil Esa es probablemente la solución que Ben necesita ... La respuesta aceptada por dlopen podría ser solo una interpretación errónea de una pregunta para principiantes (¿Ben?) ... @Ben L: Si no sabes qué hay en el. entonces tendrá problemas para usarlo con dlsym ;-) – neuro

0

Es -l que vinculan el archivo de almacenamiento como libblah.a o si agrega -PIC a gcc obtendrá un archivo 'Objeto compartido' libblah.so (es el vinculador que lo crea). Tuve un SOL una vez y he creado este tipo de archivos. Los archivos pueden tener un número de revisión que debe ser exacto o más alto (El código puede haber cambiado debido a un error). pero la llamada con parámetros debe ser la misma que la salida.

Cuestiones relacionadas