2010-05-13 38 views
5

Je travaille sur une application X11. Par défaut, mon application ne nécessite que libX11.so et les bibliothèques standard gcc C et maths. L'application peut étendre les fonctionnalités avec les systèmes audio Xfixes, Xrender et ALSA. Toutefois, ces fonctionnalités (Xfixes, Xrender et ALSA) sont facultatives.Chargement dynamique des objets partagés en utilisant dlopen()

Pour obtenir ce comportement, j'utilise le chargement à l'exécution, c.-à-d. Que libXfixes, libXrender et libasound doivent être dlopen() ed.

Par conséquent, l'application peut fonctionner en l'absence de telles bibliothèques.

Ma question:

What library names should I use when calling dlopen()? 

je l'ai fait remarquer que ceux-ci diffèrent de distro à distro.
Par exemple, sur openSUSE 11, ils sont nommés comme suit:

  • libXfixes.so
  • libXrender.so
  • libasound.so

cependant, les noms sur Ubuntu, avoir un numéro de version joint, comme ceci:

  • libXfixes.so.3
  • libXrender.so.1
  • libasound.so.2

Alors tente d'ouvrir "libXfixes.so" échouerait Ubuntu, bien que la lib est évidemment là. Il a juste un numéro de version ci-joint. Alors, comment mon application devrait-elle gérer cela?
Dois-je laisser mon application scanner manuellement/usr/lib/first pour voir quelles bibliothèques nous avons, puis en choisir une appropriée? Ou est-ce que quelqu'un a une meilleure idée?

Merci les gars,

Andy

+0

Voir aussi la réponse ici: http://stackoverflow.com/questions/15951672/loading-linux-libraries-at-runtime – AjayKumarBasuthkar

Répondre

1

Vous devez ouvrir à l'aide du SONAME de la bibliothèque. Vous pouvez le voir en utilisant readelf -d [libname]. Par exemple, sur une de mes machines Fedora Linux, le SONAME de la bibliothèque C est libc.so.6.

Les liens symboliques entre les noms .so et les noms .so.6 ne sont pas garantis.Ces liens symboliques ne sont nécessaires que pour la compilation de logiciels et ne sont généralement pas installés sur des systèmes sans les packages de développement.

De toute façon, vous ne voudriez pas charger une version avec un nombre différent, car les changements de numéro indiquent des différences API majeures.

+0

La plupart des bibliothèques sont rétrocompatibles, ce qui signifie qu'une bibliothèque avec un soname plus élevé devrait fonctionner. Dites que vous écrivez un programme qui dlopens 'libc.so.6'. Ensuite, les développeurs de libc font une mise à jour majeure et libèrent 'libc.so.7'. Maintenant, votre programme va inutilement casser parce que le soname ne correspond pas. –

+0

@ BjörnLindqvist: non, la plupart des bibliothèques * ne sont pas * rétrocompatibles. D'où tiens-tu cette idée? Et s'ils sont compatibles, ils ne changent pas le numéro de version majeur. GNU libc est sur 6 depuis longtemps maintenant. –

+0

Vous pouvez inclure et utiliser les macros fournies pour charger les différentes bibliothèques partagées de la glibc. D'autres paquets peuvent faire des choses similaires pour indiquer le nom de la bibliothèque à charger. Voir "man dlopen" pour un exemple. –

-1

D'après ce que j'ai appris, que vous venez dlopen() (par exemple) "libXfixes.so", ce qui est très probablement un lien symbolique vers le fichier le plus récent « libXfixes.so. 3" de toute façon, d'une manière similaire à celle-ci:

$ file /usr/lib/libalpm.so 
/usr/lib/libalpm.so: symbolic link to `libalpm.so.4.0.3' 

un rapide aperçu de mes «/usr/lib/» montre que presque toutes les bibliothèques il y a des liens symboliques à c'est le plus récent « .X » fichier numéroté , et je suis sûr que c'est aussi ce qui se passe sur d'autres distributions.

Seulement si vous avez besoin d'une version spécifique de la bibliothèque, vous nommez explicitement la version "libXfixes.so.2" par exemple.

+0

Voir aussi la réponse ici: http://stackoverflow.com/questions/15951672/loading -linux-libraries-at-runtime – AjayKumarBasuthkar

+0

Vous ne devez jamais débloquer le nom bare, qui est uniquement fourni par les packages de développement et ne sera pas présent sur un système de déploiement de production. –