【问题标题】:Dynamically loading two libpython versions动态加载两个 libpython 版本
【发布时间】:2011-03-20 05:49:52
【问题描述】:

我有一个嵌入了 python2 和 python3 解释器的程序。 libpython 共享库是dlopen()ed 由各自的命令提供对解释器的访问,并且每个解释器都维护自己的状态。

如果用户只使用纯 python 模块或内置函数,这一切都可以正常工作。尝试加载 C 扩展(如 termios)然后抱怨“未定义的符号:PyExc_TypeError”。发生这种情况是因为 C 扩展没有与 libpython 链接。 Python 上游不认为这是problem

为了解决这个问题,我可以将程序中的 dlopen() 调用更改为 libpython 共享库以使用 RTLD_GLOBAL。但是,一旦我这样做,尝试在程序的同一会话中同时使用 python2 和 python3 解释器会导致它在调用 Py_Initialize 的过程中为第二个调用的解释器而 ABRT。只使用一个解释器就可以了。

知道当 C 扩展不与 libpython 链接时如何使其工作,因此需要使用 RTLD_GLOBAL

【问题讨论】:

    标签: python c dynamic


    【解决方案1】:

    抱歉,这不会按您希望的方式工作。解决方案通常包括将每个扩展链接到版本化的 libpython 符号;或者可以有一个支持命名空间的链接器,这样可以将每个库映射到不同的命名空间,而不是全局的。不幸的是,这些选项都不容易应用,因此您可能会被多进程模型所困扰。只需 fork 并拥有一个指向每个 Python 版本的进程链接。那么困难的一点是如何共享导致您首先需要两个不同的 Python 解释器的任何数据。也许对导致问题的问题的描述可能有助于找到更好的解决方案?

    【讨论】:

    • 该程序允许使用 python 解释器编写脚本。它以前只支持 Python2,但最近获得了 Python3 的支持。这个想法不是强制一个选项或另一个,特别是因为已经存在使用 Python2 接口编写的脚本。我想可以更改它以跟踪一个界面是否已经加载,然后阻止另一个界面加载。这仍然提供了使用两个解释器构建的灵活性,但避免了整个崩溃问题。 :)
    • 这似乎是一种简单的解决方法,尽管有些限制。更复杂的选择是将脚本接口与语言绑定分开,通过子进程运行该接口,然后让每个子进程链接到您喜欢的任何版本。它不会那么高效,并且根据您当前的界面可能完全不切实际,但考虑到您现在可以 dlopen 它可能是可行的。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2010-12-14
    • 2011-04-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-08-31
    • 2019-03-15
    相关资源
    最近更新 更多