2010-07-23 24 views
1

我有一个程序,它嵌入两python2和python3解释。 libpython共享库由相应的命令编辑,这些命令提供对解释器的访问,并且每个解释器保持其自己的状态。动态同时加载两个版本libpython

这一切工作就好了,如果用户只使用纯Python模块或内建命令。尝试加载C扩展(如termios),然后抱怨“未定义的符号:PyExc_TypeError”。发生这种情况是因为C扩展没有链接到libpython。 Python上游不认为这是一个problem

为了解决这个问题,我可以在我的程序中更改dlopen()的调用,使libpython共享库使用RTLD_GLOBAL。但是,只要我这样做,试图在程序的同一会话中同时使用python2和python3解释器,导致它在调用Py_Initialize的过程中导致ABRT,无论哪个解释器被第二个调用。只使用其中一个解释器可以正常工作。

任何想法如何获得当C扩展将不反对libpython挂钩,因此需要使用RTLD_GLOBAL这个工作?

回答

1

对不起,但这不会按照您希望的方式工作。解决方案通常包括将每个扩展连接到版本化的libpython符号;或者可以有一个支持命名空间的链接器,这样可以将每个库映射到不同的名称空间,而不是全局的。不幸的是,这些选项都不容易应用,所以您可能会坚持使用多进程模型。只需分叉即可,并为每个版本的Python提供一个流程链接。那么艰难的是如何分享导致你需要两个不同的Python解释器的数据。也许关于什么问题导致问题的描述可能有助于找到更好的解决方案?

+0

该程序允许使用python解释器进行脚本编写。它以前只支持Python2,但最近获得了Python3的支持。这个想法并不是强迫一个选项或另一个选项,特别是因为存在已经使用Python2接口编写的脚本。我想它可能会改变,以跟踪一个接口是否已经加载,然后阻止另一个加载。这仍然可以灵活地与两个解释器一起构建,但避免了整个崩溃问题。 :) – jamessan 2010-07-23 17:47:55

+0

这似乎是一个简单的解决方法,虽然有点有限。更复杂的选择是将脚本接口与语言绑定分开,通过子进程运行该接口,然后让每个子进程链接到您喜欢的任何版本。它不会很有效率,根据您当前的界面而定,可能完全不切合实际,但考虑到您现在可以减少它,可能是可行的。 – 2010-07-23 18:30:51