1

I'm trying to use SWIG with embedded Python 3.5.2. The following is built as a Windows console app. It fails initializing the Python side SWIG module "arpy.py" when it tries to import the C++ side SWIG module "_arpy". My (probably incorrect) understanding it that the C++ side "_arpy" module should already be loaded by the SWIG module init function called from main() but this doesn't seem to be the case.

arpy.i:

%module arpy

%{
#include "arpy.h"
%}

%include <windows.i>
int test();

arpy.h:

#pragma once

int test();

swig -python -c++ arpy.i generates:
arpy_wrap.cxx
arpy.py

main.cpp:

#include <Python.h>

extern "C" PyObject* PyInit__arpy();

int main()
{
    Py_Initialize();
    PyInit__arpy(); // is this the right call to "import" the module?
    PyRun_SimpleString("import arpy");

    return 0;
}

int test()
{ 
    return 1;
}

Output:

Traceback (most recent call last):
  File "C:\Personal\Aue\Python\arpy.py", line 18, in swig_import_helper
    return importlib.import_module(mname)
  File "C:\3rdParty\lib\Python\Python-3.5.2\Lib\importlib\__init__.py", line 126, in import_module
    return _bootstrap._gcd_import(name[level:], package, level)
  File "<frozen importlib._bootstrap>", line 986, in _gcd_import
  File "<frozen importlib._bootstrap>", line 969, in _find_and_load
  File "<frozen importlib._bootstrap>", line 956, in _find_and_load_unlocked
ImportError: No module named '_arpy'

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "<string>", line 1, in <module>
  File "C:\Personal\Aue\Python\arpy.py", line 21, in <module>
    _arpy = swig_import_helper()
  File "C:\Personal\Aue\Python\arpy.py", line 20, in swig_import_helper
    return importlib.import_module('_arpy')
  File "C:\3rdParty\lib\Python\Python-3.5.2\Lib\importlib\__init__.py", line 126, in import_module
    return _bootstrap._gcd_import(name[level:], package, level)
ImportError: No module named '_arpy'

Python is running the arpy.py init code which fails using importlib.import_module on "_arpy". Calling PyInit__arpy() in main() I think should be "importing" the SWIG generated _arpy module via the CPython/C API but apparently this all doesn't work how I'm guessing.

ivan_pozdeev
  • 33,874
  • 19
  • 107
  • 152
tukra
  • 921
  • 8
  • 13
  • You need to compile your arpy_wrap.cxx into a DLL. On Windows they are renamed to `.pyd` for the generated wrapper `arpy.py` to load em – Jens Munk Oct 30 '16 at 15:39
  • Not having a separate DLL is what I'm trying to achieve. The python FAQ shows an example of this approach https://docs.python.org/3/faq/windows.html#how-can-i-embed-python-into-a-windows-application . The problem is how to get the _arpy module registered properly via the CPython/C API. It seems the SWIG generated init function in the FAQ example did that but perhaps things changed since then. The init function builds an API module object but apparently doesn't do all the step to make it seem imported. – tukra Oct 30 '16 at 16:06

1 Answers1

2

From the examples here: (https://docs.python.org/3/extending/embedding.html) I see that to import the SWIG C++ module as a builtin you need:

PyImport_AppendInittab("_arpy", &PyInit__arpy);

before calling Py_Initialize()

Things work as expected now.

tukra
  • 921
  • 8
  • 13