La construction d'une bibliothèque partagée à l'aide de gcc

RÉSOLU. Voir ci-dessous pour les corrections (étiquette FIXE).

Je vais avoir de la difficulté à créer une bibliothèque partagée à l'aide de gcc.

J'ai créé un petit exemple de projet qui correspond étroitement à la structure du projet lui-même, je travaille sur. Je l'ai fait disponibles en tant que tar.gz archive ici:

http://209.59.216.197/libtest.tar.gz

FIXE: j'ai fait la version fixe disponibles ici:

http://209.59.216.197/libtest_fixed.tar.gz

Dans cet exemple de projet, j'ai une application (app) qui charge une bibliothèque partagée que j'ai écrit (libshared.donc) au moment de l'exécution et appelle une fonction de la bibliothèque partagée définit: function_inside_shared_lib().

À son tour, cette bibliothèque partagée utilise une fonction définie à l'intérieur d'une bibliothèque statique (libstatic.a): function_inside_static_lib().

Le problème, c'est quand j'ai construit la bibliothèque partagée, le symbole "function_inside_shared_lib" n'est pas exporté. J'ai examiné la bibliothèque partagée à l'aide de "nm" et le symbole n'était pas là. Je me demandais si la commande j'utilise pour créer la bibliothèque partagée est correct:

g++ -g -ggdb -fPIC-rdynamic -I ../statique -c shared.cpp -o partagé.o

g++ -g -ggdb -fPIC-rdynamic -partagé -L ../statique -lstatic -o libshared.donc

FIXE: Les commandes correctes sont les suivantes:

g++ -g -ggdb -fPIC-rdynamic -I../statique -c shared.cpp -o partagé.o

g++ -g -ggdb -fPIC-rdynamic -partagé -L../statique -o libshared.donc partagé.o -lstatic

J'ai essayé ces commandes avec et sans -rdynamic, ainsi qu'avec et sans l'option-fPIC. Les résultats sont toujours les mêmes.

J'utilise Ubuntu 10.04 (64-bit) avec g++ version 4.4.3.

La totalité de l'échantillon projet suit. (Ou vous pouvez télécharger l'archive en utilisant le lien en haut de mon post).

serg@rongeurs:~/libtest$ ls

app partagé statique

Ici sont les trois composantes:

Composante 1: Une bibliothèque statique qui définit une fonction appelée function_inside_static_lib().

Elle comprend les éléments suivants:

serg@rodent:~/libtest$ cd static/  
serg@rodent:~/libtest/static$ ls  
static.cpp  static.h

statique.h

//Header file for the static library

int function_inside_static_lib(int arg1, int arg2);

static.cpp

//Source file for the static library

#include <iostream>
using namespace std;

#include "static.h"

int function_inside_static_lib(int arg1, int arg2)
{
    cout << "In function_inside_static_lib()" << endl;

    //Return the sum
    int result = arg1 + arg2;
    return result;
}

Composante 2: Une bibliothèque partagée qui utilise la bibliothèque statique et définit une nouvelle fonction.

serg@rongeurs:~/libtest$ cd partagé

serg@rongeurs:~/libtest/shared$ ls

partagé.rpc

shared.cpp

//The shared library only has one source file.

//The shared library uses the static one.
#include "static.h"

#include <iostream>
using namespace std;

int function_inside_shared_lib(int arg1, int arg2)
{
    cout << "In function_inside_shared_lib()" << endl;

    cout << "Calling function_inside_static_lib()" << endl;
    int result = function_inside_static_lib(arg1, arg2);

    return result;
}

Composante 3: Une application qui utilise la bibliothèque partagée.

serg@rongeurs:~/libtest$ cd app

serg@rongeurs:~/libtest/app$ ls

app.rpc

app.cpp

FIXE: Parce que le C++ symboles se déchire, le bon nom de la fonction de recherche est _Z26function_inside_static_libii au lieu de function_inside_static_lib

//The application loads the shared library at runtime.

#include <dlfcn.h>
#include <iostream>

using namespace std;

int main(int argc, char **argv)
{
    void *handle;
    int (*function_inside_shared_lib)(int, int);
    char *error;

    int arg1 = 3;
    int arg2 = 7;

    cout << "app: loading the shared library." << endl;
    handle = dlopen ("libshared.so", RTLD_LAZY);
    if (!handle) {
        cout << "Error: Failed to open shared library." << endl;
        cout << dlerror() << endl;
        return -1;
    }

    cout << "app: Looking for function_inside_shared_lib" << endl;

    //The next line is now FIXED:
    function_inside_shared_lib = (int (*)(int, int))dlsym(handle, "_Z26function_inside_static_libii");

    if ((error = dlerror()) != NULL)  {
        cout << "Error: Could not find the function." << endl;
        cout << error << endl;
        return -1;
    }

    cout << "app: Calling function_inside_shared_lib(" << arg1 << ", " << arg2 << ")" << endl;
    int result = (*function_inside_shared_lib)(arg1, arg2);

    cout << "app: The result is " << result << endl;

    dlclose(handle);
    return 0;
}

Voici les commandes que j'utilise pour construire l'ensemble de ces composants. Notez que je veux les symboles de débogage pour être disponible dans le final de l'application. Idéalement, je veux être capable de faire une trace à l'intérieur de l'application et de voir les symboles de la fois la bibliothèque partagée et la bibliothèque statique.

1: la Construction de la bibliothèque statique. Je pense que je suis à l'aise avec cette étape:

serg@rongeurs:~/libtest/static$ g++ -g -ggdb -c static.cpp -o statique.o # Voir la version FIXE juste en dessous

serg@rongeurs:~/libtest/static$ ar rcs libstatic.un statique.o

serg@rongeurs:~/libtest/static$ ls

libstatic.un static.cpp statique.h statique.o

FIXE: La première commande ci-dessus doit comporter-fPIC. Le bon de commande est

g++ -g -ggdb -fPIC-c static.cpp -o statique.o

2: la Construction de la bibliothèque partagée. Je suis sûr que c'est là que je vais mal.

serg@rongeurs:~/libtest/shared$ g++ -g -ggdb -fPIC-rdynamic -I ../statique -c shared.cpp -o partagé.o

serg@rongeurs:~/libtest/shared$ g++ -g -ggdb -fPIC-rdynamic -partagé -L ../statique -lstatic -o libshared.donc, # Voir juste ci-dessous pour la version FIXE
serg@rongeurs:~/libtest/shared$ ls

libshared.donc shared.cpp partagé.o

FIXE: La deuxième commande ci-dessus doivent être:

g++ -g -ggdb -fPIC-rdynamic -partagé -L../statique -o libshared.donc partagé.o -lstatic

À ce point, si je run nm pour examiner les symboles à l'intérieur de libshared.donc, je ne vois pas function_inside_shared_lib() n'importe où, même avec l'-et -D options pour nm. (Cependant, je ne voir à l'intérieur partagée.o).

EDIT: Avec le correctif ci-dessus, le symbole apparaît comme _Z26function_inside_shared_libii.

3: la Construction de l'application:

Tout d'abord, copiez la bibliothèque partagée dans le dossier app:

serg@rongeurs:~/libtest$ cp partagé/libshared.donc app/

serg@rongeurs:~/libtest$ cd app

serg@rongeurs:~/libtest/app$ ls

app.rpc libshared.donc

Maintenant compiler:

serg@rongeurs:~/libtest/app$ g++ -g -ggdb -ldl -L. -lshared app.cpp -o app

serg@rongeurs:~/libtest/app$ ls

app app.cpp libshared.donc

Si j'essaie de le lancer:

serg@rongeurs:~/libtest/app$ ./app

app: le chargement de la bibliothèque partagée.

application: la Recherche d'function_inside_shared_lib

Erreur: impossible de trouver la fonction.

/home/serg/libtest/app/libshared.so: undefined symbol: function_inside_shared_lib

Cela a un sens parce que je ne pouvais pas voir function_inside_shared_lib() à l'aide de nm, ce qui signifie que je suis probablement la construction de la bibliothèque partagée de manière incorrecte à l'étape 2.

Comment puis-je réparer ma commande dans la deuxième étape, de sorte que function_inside_shared_lib est exporté correctement?

Aussi n'hésitez pas à me donner d'autres conseils si vous remarquez que je suis en train de faire quelque chose de bizarre. Je suis encore un débutant.

tldp.org/HOWTO/Program-Library-HOWTO/shared-libraries.html
La commande pour la construction de l'objet partagé de bibliothèque n'a pas l'air de droit -, il ne mentionne pas partagé.o. Avez-vous tapé correctement?
Est-ce une question ou dix-sept questions ou des dix-sept réponses? Je ne peux pas en dire plus...
Question similaire - stackoverflow.com/questions/14884126/...

OriginalL'auteur Sergey K | 2010-08-27