我知道 Cython 的目的是创建 Python 扩展模块,但是用 Cython 制作的编译库可以由非 Python 程序加载吗?如果不是,为什么?
2 回答
我怀疑您是否可以直接在非 python 程序上加载它们;查看由最简单的 Cython 脚本生成的 C 代码,很明显您需要所有 Python 脚手架才能使其工作。也就是说,您可以间接地做到这一点,例如从 C++ 中。在 C++ 中,我使用boost.python嵌入Python解释器并加载我的一些模块和脚本。这可能看起来很复杂,但允许您快速使用您已经从 C++ 用 Python 编写的任何扩展,前提是您构建了适当的粘合代码(请参阅boost.python wiki)。
这种方法的缺点是你实际上是在加载一个完整的 Python 解释器,只是为了能够使用一些扩展。这对我来说不是问题,因为我已经有了 python 扩展并且正在我的应用程序中嵌入 Python 以提供基本的脚本能力,但我不会使用这种方法来编写新的库。
您可以通过两种机制使 cdef
'ed Cython 结构在外部可用:
- 使用
cdef public
声明——和/或也 - 使用
api
关键字。
这是来自上述页面的两种机制的示例之一:
cdef public struct Vehicle:
int speed
float power
cdef api void activate(Vehicle *v):
if v.speed >= 88 and v.power >= 1.21:
print "Time travel achieved"
这些方法中的每一个都将指示 Cython 编译器生成一个头文件(“.h”),然后您可以将其与您的正交 C/C++ 项目集成。
声明产生一个cdef public
名为modulename.h
;的文件。使用此文件中的结构将要求您链接已编译的 Cython 扩展模块。
声明(如果您愿意,api
可以与 同时使用)产生一个文件;使用基于 - 的标头的代码不需要链接到扩展模块 - 但它需要调用'd 函数,然后才能使用任何 API 代码(NumPy 的 Cython 倾向用户会发现熟悉的策略)。cdef public
modulename_api.h
api
cdef
import_modulename()
以我个人的经验,只要结构布局与消费代码很好地吻合,并且您愿意在手动管理 GIL您的 C/C++ 代码以使事情正常进行。