web-dev-qa-db-fra.com

Comment charger un objet partagé en C++?

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

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

#include "headerforClassFromBlah.h"

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

    ClassFromBlah a;
    a.DoSomething();
}

Je suppose que cette question est vraiment fondamentale, mais je ne trouve rien qui me saute aux yeux lorsque je cherche sur le Web.

19
Ben L

Il existe deux manières de charger des objets partagés en C++.

Pour l’une ou l’autre de ces méthodes, vous aurez 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;
}

* Volé dans dlopen man page Linux Le processus sous Windows ou sur toute autre plate-forme est identique, il suffit de remplacer dlopen par la version de plate-forme de la recherche dynamique de symboles.

Pour que la méthode dynamique fonctionne, tous les symboles que vous souhaitez importer/exporter doivent avoir une liaison C externe.

Il y a quelques mots Ici sur le moment d'utiliser des liens statiques et des liens dynamiques.

39
Salgar

Cela dépend de la plate-forme. Pour le faire au moment de l'exécution, sous Linux, vous utilisez dlopen , sous Windows, vous utilisez LoadLibrary .

Pour le faire au moment de la compilation, vous devez exporter le nom de la fonction sous Windows à l’aide de dllexport et dllimport . Sur linux, gcc exporte tous les symboles publics afin que vous puissiez simplement y accéder normalement et appeler la fonction. Dans les deux cas, cela nécessite généralement d'avoir le nom du symbole dans un fichier d'en-tête que vous avez ensuite #include, puis de vous lier à la bibliothèque à l'aide des fonctionnalités de votre compilateur.

5
1800 INFORMATION

Vous devez # inclure tous les en-têtes associés à la bibliothèque partagée pour obtenir les descriptions de choses comme ClassFromBlah. Vous devez ensuite établir un lien avec le .so - la façon dont cela fonctionne dépend de votre compilateur et de votre instalation générale, mais pour g ++, quelque chose comme:

g++ myfile.cpp -lblah

va probablement fonctionner.

3
anon

C'est -l qui lie le fichier 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 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 été modifié à cause d'un bogue). mais l'appel avec les paramètres doit être identique à la sortie.

0
user3213642