2010-07-23 5 views
1

J'ai un programme qui incorpore à la fois les interpréteurs python2 et python3. Les librairies partagées par libpython sont dlopen() éditées par les commandes respectives qui fournissent l'accès aux interpréteurs et chaque interpréteur maintient son propre état.Chargement dynamique de deux versions de libpython

Tout cela fonctionne très bien si l'utilisateur utilise uniquement des modules python ou des builtins. Essayer de charger une extension C (comme termios) se plaint alors de "symbole indéfini: PyExc_TypeError". Cela arrive parce que les extensions C ne sont pas liées à libpython. Python en amont ne pense pas que ce soit un problem. Pour contourner cela, je peux changer les appels dlopen() dans mon programme pour que les librairies partagées libpython utilisent RTLD_GLOBAL. Dès que je fais cela, cependant, en essayant d'utiliser à la fois les interpréteurs python2 et python3 dans la même session du programme l'amène à ABRT dans le processus d'appel Py_Initialize pour n'importe quel interpréteur a été invoqué en second lieu. Utiliser seulement un des interprètes fonctionne bien.

Une idée de comment cela fonctionnera quand les extensions C ne seront pas liées à libpython, nécessitant donc l'utilisation de RTLD_GLOBAL?

Répondre

1

Désolé, mais cela ne fonctionnera pas comme vous le souhaitez. La solution consisterait normalement à lier chaque extension à des symboles libpython versionnés; ou on pourrait avoir un éditeur de liens capable de créer un espace de noms, de telle sorte que l'on pourrait mapper chaque bibliothèque à un espace de noms différent, plutôt que global. Malheureusement, aucune de ces options n'est facile à appliquer, donc vous êtes probablement bloqué avec un modèle multi-processus. Il suffit de taper et d'avoir un lien vers chaque version de Python. Le plus difficile est donc de savoir comment partager les données qui vous ont conduit à avoir besoin de deux interpréteurs Python distincts en premier lieu. Peut-être une description du problème qui a conduit à la question peut-elle aider à trouver une meilleure solution?

+0

Le programme permet d'utiliser l'interpréteur python pour les scripts. Auparavant, il ne supportait que Python2 mais il a récemment pris en charge Python3. L'idée n'était pas de forcer une option ou l'autre, d'autant plus qu'il existe des scripts déjà écrits utilisant l'interface Python2. Je suppose qu'il pourrait être changé pour garder une trace si une interface a déjà été chargée, puis empêcher l'autre de chargement. Cela donne encore la flexibilité de construire avec les deux interpréteurs mais évite tout le problème de plantage. :) – jamessan

+0

Cela semblerait la solution de contournement facile, quoique quelque peu limitée. L'option la plus complexe consiste à séparer votre interface de script des liaisons de langage, à exécuter cette interface via des sous-processus, puis à laisser chaque sous-processus se lier à la version de votre choix. Ce ne sera pas aussi efficace, et peut être totalement impraticable selon votre interface actuelle, mais peut être faisable étant donné que vous pouvez le dlopen maintenant. –

Questions connexes