动态加载两个libpython版本

1 投票
1 回答
808 浏览
提问于 2025-04-16 01:44

我有一个程序,它同时嵌入了 Python2 和 Python3 的解释器。这些解释器的共享库是通过 dlopen() 命令加载的,这样就可以访问到它们,而每个解释器都有自己的状态。

如果用户只使用纯 Python 模块或者内置功能,这一切都运行得很好。但是,当尝试加载一个 C 扩展(比如 termios)时,就会出现“未定义的符号:PyExc_TypeError”的错误。这是因为这些 C 扩展没有和 libpython 连接起来。Python 的开发团队认为这并不是一个 问题

为了绕过这个问题,我可以在程序中修改 dlopen() 调用,使其在加载 libpython 共享库时使用 RTLD_GLOBAL。然而,一旦这样做,尝试在同一个程序会话中使用 Python2 和 Python3 的解释器,就会导致程序在调用第二个被调用的解释器的 Py_Initialize 时崩溃。只使用其中一个解释器是没问题的。

有没有办法解决这个问题,让 C 扩展不需要和 libpython 连接,因此需要使用 RTLD_GLOBAL 呢?

1 个回答

1

抱歉,这个方法可能无法达到你想要的效果。通常情况下,解决这个问题的方法是把每个扩展链接到不同版本的libpython符号;或者可以使用一个支持命名空间的链接器,这样就能把每个库映射到不同的命名空间,而不是使用全局的命名空间。不过,这两种方法都不容易实现,所以你可能需要采用多进程的方式。简单来说,就是创建多个进程,每个进程链接到不同版本的Python。接下来比较棘手的是,如何共享那些让你需要两个不同Python解释器的数据。也许描述一下是什么问题导致你有这个疑问,可能会帮助找到更好的解决方案。

撰写回答