Cython 主要是为生成 Python 扩展模块而设计的,并不是真正为支持其他插件 API 而设计的。但是,如果您愿意手动调整输出,您可能会得到一些合理的东西。
例如,您可以手动编写一个小的 C 存根来将您的模块初始化为 gstreamer 插件:
#include "Python.h"
#include "gst_plugin.h"
static gboolean plugin_init (GstPlugin *plugin) {
// initialize the extension module
#if PY_MAJOR_VERSION < 3
initgstreamer();
#else
PyInit_gstreamer();
#endif
// call into function exported from cython module
return register_plugin(plugin);
}
GST_PLUGIN_DEFINE (
GST_VERSION_MAJOR,
GST_VERSION_MINOR,
my_filter,
"My filter plugin",
plugin_init,
VERSION,
"LGPL",
"GStreamer",
"http://gstreamer.net/"
)
register_plugin
然后,您可以从 cython 模块中导出该函数:
cdef public int register_plugin(void *plugin):
# use the gstreamer API in here to register your plugin
然而,这还不是全部。为了让它工作,你必须以某种方式说服 gstreamer 加载libpython
到它的进程中,因为 cython 依赖它甚至只是初始化。您可能需要稍微初始化 Python 解释器,然后您的代码才能按您的意愿运行。您需要为要使用的所有 gstreamer 插件注册 API 定义 cython 存根。如果其他人试图在同一个 gstreamer 进程中做同样的事情,它可能都会分崩离析。
综上所述,更直接的方法可能是制作一个 gstreamer 插件来桥接 Python 代码,然后使用该插件访问您的 cython 模块。这样,python 嵌入是显式的,您将有机会在加载代码之前正确初始化 Python 解释器。这样的插件对于尝试与您进行类似项目的其他人可能很有用,无论是使用 cython 还是ctypes
模块。
这样的插件实际上是一个颠倒的 PyGST:它将 Python 作为库加载到 GStreamer 中,而不是将 GStreamer 作为库加载到 Python 中。可能有一些 PyGST 代码可以重复用于此目的,但仍然存在每个进程只能包含一个 Python 的限制,因此使用这种机制的多个模块都需要共享同一个 Python 解释器,就像什么时候一样多个应用程序被加载到mod_python
Apache 网络服务器的模块中。