Swig/python:啥时候需要 SWIG_init()?
Posted
技术标签:
【中文标题】Swig/python:啥时候需要 SWIG_init()?【英文标题】:Swig/python : when SWIG_init() is needed?Swig/python:什么时候需要 SWIG_init()? 【发布时间】:2018-07-03 13:47:44 【问题描述】:大家好,感谢您尝试帮助我!
尝试导入 swig 生成的 python 模块时遇到问题。 我有一个包含几个方法的基本库“示例”。 在它旁边,我有一个动态链接到 python 的主程序。 该程序导入生成的模块并在其中调用函数。
如果我的库示例是共享的,名为 _example.so,一切正常,我可以在 python 中导入它。
但如果我的库是静态库 _example.a 并链接到主程序,那么除非我在主函数中添加对 SWIG_init() 的调用,否则我将收到错误“找不到名为 _example 的模块”。
SWIG_init() 究竟是什么,我应该什么时候使用它?这对我来说似乎很奇怪,因为文档中从未说过要进行这样的调用。
我知道处理 .so 共享库会更好,但我尝试重现我在工作中的大型项目中的行为,所以我真的必须了解当模块是静态时会发生什么。
这是我的主要文件:
#include "Python.h"
#include <iostream>
#if PY_VERSION_HEX >= 0x03000000
# define SWIG_init PyInit__example
#else
# define SWIG_init init_example
#endif
#ifdef __cplusplus
extern "C"
#endif
#if PY_VERSION_HEX >= 0x03000000
PyObject*
#else
void
#endif
SWIG_init(void);
int main (int arc, char** argv)
Py_Initialize();
SWIG_init(); // needed only using the statically linked version of example ?
PyRun_SimpleString("print \"Hello world from Python !\"");
PyRun_SimpleString("import sys");
PyRun_SimpleString("sys.path.append(\"/path/to/my/module\")");
PyRun_SimpleString("import example");
PyRun_SimpleString("a = example.Example()");
PyRun_SimpleString("print a.fact(5)");
以下是事物的生成方式:
swig -c++ -python example.i
g++ -fpic -c example.cpp example_wrap.cxx -I/include/python2.7 -lstdc++
ar rvs libexample.a example.o example_wrap.o
// to generate dynamic instead of static : g++ -shared example.o example_wrap.o -o _example.so
g++ main.cpp -I/include/python2.7 libexample.a -lstdc++ -L/lib/python -lpython2.7 -o main
【问题讨论】:
【参考方案1】:您调用的是由 SWIG 生成的 python 包装器加载的本机 python 模块 _example
的 init 函数。对于 python 2,此函数名为 init_example
,对于 python 3 it is named PyInit__example
。
每个python extension with C or C++ 都需要这样一个函数,它基本上初始化所有东西并注册模块的名称和所有可用的方法。在您的情况下,SWIG 已为您生成此函数。
当你静态编译库时你必须自己调用这个函数的原因很简单,python 包装器示例导入了本地模块 _example,按照 python 约定,它是一个共享对象,你没有编译它,因此没找到。
通过调用 SWIG_init,您“预加载”了模块,因此 python 不会尝试重新导入它,因此即使 python 模块路径上的任何地方都没有共享对象,它也可以工作。
如果你的模块有共享对象,python会在加载共享对象后为你调用这个函数,你不必担心这个。
【讨论】:
非常感谢!我不太清楚是否可以在不重建解释器的情况下将静态库用作模块。现在我明白了为什么这个电话会完成。再次感谢!以上是关于Swig/python:啥时候需要 SWIG_init()?的主要内容,如果未能解决你的问题,请参考以下文章