首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Swig/python :何时需要SWIG_init()?

Swig/python :何时需要SWIG_init()?
EN

Stack Overflow用户
提问于 2018-07-03 13:47:44
回答 1查看 509关注 0票数 0

大家好,谢谢你们帮助我!

当试图导入由swig生成的python模块时,我遇到了麻烦。我有一个包含几个方法的基本库“示例”。接下来,我有一个动态链接到python的主程序。这个程序导入生成的模块并在其中调用一个函数。

如果我的库示例是一个共享的示例,名为_example.so,那么所有东西都能很好地工作,并且我可以在python中导入它。

但是,如果我的库是静态的,_example.a,并链接到主程序,那么除非在主函数中添加对SWIG_init()的调用,否则就会出现“找不到名为_example的模块”的错误。

SWIG_init()究竟是什么?我应该在什么时候使用它?对我来说,这似乎很奇怪,因为在文档中从来没有说过要进行这样的调用。

我知道处理.so共享库更好,但是我尝试复制我在工作中的大型项目的行为,所以我真的必须了解当模块是静态的时候会发生什么。

这是我的主要文件:

代码语言:javascript
复制
#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)");
}

以下是生成事物的方式:

代码语言:javascript
复制
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
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2018-07-03 16:27:06

您正在调用的是本机python模块_example的init函数,它是由SWIG生成的python包装器加载的。对于python2,这个函数名为init_example,对于PyInit__example是这样的。

每个带有C或C++的python扩展都需要这样的函数,它基本上初始化了所有的东西,注册了模块的名称和所有可用的方法。在您的情况下,SWIG已经为您生成了这个函数。

静态编译库时必须亲自调用此函数的原因很简单,因为python包装器示例导入本机模块_example,根据python约定,它是一个共享对象,您没有编译该对象,因此找不到。

通过调用SWIG_init,您可以“预加载”模块,这样python就不会尝试重新导入它,所以即使python模块路径上没有共享对象,它也能工作。

如果您有模块的共享对象,python将在加载共享对象之后为您调用这个函数,您不必担心这一点。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/51156263

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档