简体   繁体   English

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

[英]Swig/python : when SWIG_init() is needed?

Hi everyone and thanks for trying to help me ! 大家好,感谢您对我的帮助!

I encounter trouble when trying to import a python module generated by swig. 尝试导入swig生成的python模块时遇到麻烦。 I have a basic library "example" containing few methods. 我有一个包含一些方法的基本库“示例”。 Next to it I have a main program dynamically linked to python. 在它旁边,我有一个动态链接到python的主程序。 This program imports the generated module and calls a function in it. 该程序将导入生成的模块并在其中调用一个函数。

If my library example is a shared one, named _example.so, everything works perfectly, and I can import it in python. 如果我的库示例是一个名为_example.so的共享库示例,则一切运行正常,我可以将其导入python中。

But if my library is static, _example.a, and linked to the main program, then I will have the error "no module named _example was found" unless I add a call to SWIG_init() in the main function. 但是,如果我的库是静态的_example.a,并链接到主程序,则除非我在主函数中添加对SWIG_init()的调用,否则将出现错误“找不到名为_example的模块”。

What exactly does SWIG_init() , and when should I use it ? SWIG_init()究竟是什么?何时应使用它? It seems quite weird to me because it's never said in the documentation to do such a call. 对我来说似乎很奇怪,因为在文档中从未说过要进行这样的调用。

I know that dealing with a .so shared library is better but I try to reproduce the behavior of what I have on a big project at work, so I really have to understand what happens when the module is static. 我知道处理一个.so共享库更好,但是我尝试重现我在工作的大型项目中的行为,因此我真的必须了解模块静态时会发生什么。

Here is my main file : 这是我的主文件:

#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)");
}

Here is how things are generated : 这是事物的产生方式:

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

What you are calling is the init function of the native python module _example that is loaded by the SWIG generated python wrapper. 您正在调用的是由SWIG生成的python包装器加载的本机python模块_example的init函数。 For python 2 this function is named init_example , and for python 3 it is named PyInit__example . 对于python 2,此函数名为init_example ,对于python 3 ,此函数名为PyInit__example

Every python extension with C or C++ needs such a function, it basically initializes everything and registers the name of the module and all the methods available for it. 每个具有C或C ++的python扩展都需要这样的功能,它基本上会初始化所有内容并注册模块的名称和所有可用的方法。 In your case SWIG has generated this function for you. 在您的情况下,SWIG已为您生成了此功能。

The reason you have to call this function yourself when you compiled the library statically is simply that the python wrapper example imports the native module _example which is by the python convention a shared object, which you did not compile, and which is thus not found. 静态编译库时必须自己调用此函数的原因仅仅是python包装器示例导入了本机模块_example,根据python约定,该模块是一个共享对象,您没有编译该共享对象,因此找不到该共享对象。

By calling SWIG_init, you "preload" the module, so python does not try to reimport it, so it works even though there is no shared object anywhere on the python module path. 通过调用SWIG_init,您可以“预加载”模块,因此python不会尝试重新导入它,因此即使python模块路径上的任何地方都没有共享对象,它也可以正常工作。

If you have the shared object for your module, python will call this function for you after loading the shared object and you don't have to worry about this. 如果您有模块的共享库,则python在加载共享库后将为您调用此函数,而您不必为此担心。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM