2009-07-17 10 views
15

J'ai un objet partagé (une sorte - l'équivalent Linux d'une DLL Windows) que je voudrais importer et utiliser avec mon code de test.Comment charger un objet partagé en C++?

Je suis sûr que ce n'est pas ce simple;) mais c'est le genre de chose que je voudrais faire ..

#include "headerforClassFromBlah.h" 

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

    ClassFromBlah a; 
    a.DoSomething(); 
} 

Je suppose que cela est vraiment une question de base, mais je ne peux pas trouver quelque chose qui me saute sur le web.

+0

Peut-être que je suis confus mais vous ne semblez pas avoir assez d'informations là-bas. Que contient blah.so, par exemple? Vous êtes sûr que vous ne parlez pas simplement d'utiliser une référence? – Goz

+0

Que voulez-vous dire par "partagé" exactement? – Klaim

+0

Err ... donc les fichiers ne sont pas des fichiers de code, non? Peut-être que vous voulez récupérer un objet d'un.Donc (fichier de bibliothèque partagée)? – Klaim

Répondre

33

Il y a deux façons d'objets partagés de chargement en C++

Pour l'une de ces méthodes que vous avez toujours besoin du fichier d'en-tête de l'objet que vous souhaitez utiliser. L'en-tête contiendra les définitions des classes ou des objets que vous souhaitez utiliser dans votre code.

statiquement:

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

gcc yourfile.cpp -lblah 

Dynamiquement (Sous 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; 
} 

* Stolen de dlopen Linux man page Le processus sous Windows ou toute autre plate-forme est le même, il suffit de remplacer dlopen avec la version plates-formes de la recherche dynamique de symboles. Pour que la méthode dynamique fonctionne, tous les symboles que vous voulez importer/exporter doivent avoir une liaison C extern'd.

Il y a des mots Here pour savoir quand utiliser la statique et quand utiliser la liaison dynamique.

+5

+1. Peut-être vaut-il une mention explicite que dlopen est POSIX, pas C ou C++. Sur certaines plateformes, il n'y a pas de chargement dynamique, mais ils sont toujours conformes aux implémentations C++. –

+0

Quelle est la commande pour construire ce fichier, g ++ filename.cpp -L someIncludes -0 fichier de travail? –

+0

Vous aurez besoin de lier en utilisant -ldl aussi –

4

Cela dépend de la plate-forme. Pour le faire à l'exécution, sous Linux, vous utilisez dlopen, sous Windows, vous utilisez LoadLibrary. Pour le faire à la compilation, sous Windows, vous exportez le nom de la fonction en utilisant dllexport et dllimport. Sur linux, gcc exporte tous les symboles publics de sorte que vous pouvez simplement lier normalement et appeler la fonction. Dans les deux cas, cela nécessite généralement que vous ayez le nom du symbole dans un fichier d'en-tête que vous avez alors #include, puis vous liez à la bibliothèque en utilisant les fonctionnalités de votre compilateur.

3

Vous devez #inclure tous les en-têtes associés à la bibliothèque partagée pour obtenir les déclrarations de choses comme ClassFromBlah. Vous devez ensuite créer un lien contre la .so - exactement comment vous faites cela dépend de votre compilateur et instalation général, mais pour g ++ quelque chose comme:

g++ myfile.cpp -lblah 

ne fonctionnera probablement.

+0

J'ai inclus les en-têtes et je peux compiler et lier mon code avec l'objet partagé mais je n'ai aucune idée de comment l'utiliser et les classes qu'il contient - je ne l'ai pas précisé, voir ma mise à jour pour l'extrait de code. Des idées? –

+1

Quant à savoir comment utiliser les classes qu'il contient, vous avez à RTFM, j'ai peur. –

+0

@neil C'est probablement la solution dont Ben a besoin ... La réponse dlopen acceptée pourrait être juste une mauvaise interprétation d'une question débutant (Ben?) ... @Ben L: Si vous ne savez pas ce que sont dans le. donc vous aurez du mal à l'utiliser avec dlsym ;-) – neuro

0

C'est -l qui lie le fichier d'archive comme libblah.a ou si vous ajoutez -PIC à gcc, vous obtiendrez un fichier 'objet partagé' libblah.so (c'est l'éditeur de liens qui le construit). J'ai eu un SOLEIL une fois et j'ai construit ce type de fichiers. Les fichiers peuvent avoir un numéro de révision qui doit être exact ou supérieur (le code peut avoir changé en raison d'un bogue). mais l'appel avec les paramètres doit être identique à la sortie.