fonctions Redéfinition des bibliothèques dynamiques
-
09-10-2019 - |
Question
Bonjour, j'ai un programme avec une fonction globale que je voudrais personnaliser au moment de l'exécution. Dites, il existe de nombreuses versions de la fonction foo () sur les bibliothèques partagées dispersés. Maintenant, selon la configuration du système détecté au moment de l'exécution, je voudrais utiliser la fonction de bibliothèque appropriée.
loader.cpp du fichier:
#include <dlfcn.h>
#include <iostream>
void __attribute__((weak)) foo();
int main(int argc, char *argv[])
{
void* dl = dlopen("./other.so", RTLD_NOW | RTLD_GLOBAL);
if (!dl)
{
std::cerr << dlerror() << std::endl;
return 1;
}
if (foo)
{
foo();
}
else
{
std::cerr << "No foo?" << std::endl;
}
dlclose(dl);
return 0;
}
other.cpp du fichier:
#include <iostream>
void foo()
{
std::cout << "FOO!" << std::endl;
}
Je compile le programme avec
g++ -Wall -fPIC -o loaded loader.cpp -ldl
g++ -Wall -fPIC -shared -o other.so other.cpp
Cependant, le symbole faible n'est pas outrepassée. Tous les conseils?
La solution
Les symboles sont résolus pendant le temps de chargement de l'image dans laquelle ils sont référencés. Ainsi, lorsque votre exécutable est chargé, la référence à foo est déjà résolu. A la suite DLOpen ne va pas et rebind tous les symboles -. Il ne peut affecter des charges plus tard
Vous devrez utiliser dlsym à la place, ou un ensemble LD_PRELOAD:
martin@mira:/tmp$ LD_PRELOAD=/tmp/other.so ./loaded
FOO!
Autres conseils
Vous avez compilé le partage avec lib g ++. En conséquence, le nom de la fonction est mutilée:
$ nm -S other.so |grep foo
0000000000000690 000000000000002e T _Z3foov
Si vous faites un pur code C et Compiler gcc au lieu de g ++, vous trouverez fonctionner comme prévu.
Vous pouvez également définir comme suit:
extern "C" void foo()
{
std::cout << "FOO!" << std::endl;
}