可以将Cython模块静态链接到嵌入Python的可执行文件中吗?
我现在有一个用C++编译的可执行文件,这个文件里面嵌入了Python。这个嵌入的可执行文件会运行一个Python脚本,而这个脚本会加载几个Cython模块。Cython模块和可执行文件都是链接到一个共享库的。
我想把这个共享库直接放进可执行文件里,也就是说通过静态链接的方式把共享库和可执行文件结合起来。
我能把Cython模块静态链接到这个嵌入Python的可执行文件里吗?处理这种情况的最佳方法是什么?
1 个回答
是的,这是可能的,但前提是你对Python解释器有一定了解。我接下来要描述的内容是针对在iOS平台上使用Python的。你需要了解如何让Python识别你的模块,如果你不想修改原始的Python解释器(把TEST替换成你自己的标签或库名)。
一种可能的方法是:
编译你自己的Python,并使用一个动态加载补丁,这个补丁会优先选择不使用dlopen()来加载你的模块,而是直接用dlsym()来检查模块是否已经在内存中。
创建一个libTEST.a文件,里面包含在构建过程中生成的所有.o文件(而不是.so文件)。这些文件通常可以在
build/temp.*
中找到,然后你可以做类似这样的操作:ar rc libTEST.a build/temp.*/*.o ranlib libTEST.a
在编译主可执行文件时,你需要在编译命令行中添加对新libTEST.a的依赖,具体方式是:
-lTEST -L.
这样做的结果是,你会得到一个包含所有Cython模块符号的可执行文件,Python就能在内存中找到它们。
(举个例子,我使用了一个增强的包装器,在编译时重定向ld,以避免生成.so文件,而是最终生成一个.a文件。在kivy-ios项目中,你可以找到liblink,它用于生成.o文件,还有biglink,用于抓取所有目录中的.o文件并生成.a文件。你可以在build_kivy.sh中查看它是如何使用的。)