Windows中的SWIG生成C ++ Python3包装器导致断言MSVC 2017

时间:2018-11-14 13:16:31

标签: python c++ swig

使用SWIG围绕C ++类生成包装器会在运行时引起奇怪的断言:

Assertion failed!

Program: C:\Python37\python37_d.dll
File: c:\_work\4\s\objects\typeobject.c
Line: 3634

Expression: PyTuple_Check(args)

For information on how your program can cause an assertion
failure, see the Visual C++ documentation on asserts

(Press Retry to debug the application - JIT must be enabled)

如果在弹出的对话框中单击“忽略”,则一切正常。

我创建了一个示例程序来尝试复制问题并遇到相同的问题:

main.cpp

#include "testwrapper.h"

#pragma push_macro("slots")
#undef slots
#include "Python.h"
#pragma pop_macro("slots")

#include "SwigModules/generated/swig_runtime.h"

PyObject * ConvertToWrapper(SwigInterface * instance)
{
    swig_type_info * pTypeInfo = SWIG_TypeQuery("SwigInterface *");
    PyObject* obj = SWIG_NewPointerObj(instance, pTypeInfo, 0); <- issue occurs here
    return obj;
}

TestWrapper * wrapper = new TestWrapper();

void TestSwig()
{
  Py_Initialize();
  PyRun_SimpleString("import test_module");
  ConvertToWrapper(wrapper);
  Py_Finalize();
}

int main(int argc, char *argv[])
{
  TestSwig();
  return 0;
}

testwrapper.h

#pragma once
#include "swiginterface.h"

class TestWrapper : public  SwigInterface
{
public:
  TestWrapper(){}
  virtual ~TestWrapper(){}
  virtual void Test();
};

swiginterface.h

#pragma once

class SwigInterface
{
public:
  virtual ~SwigInterface(){}
  virtual void Test() = 0;
};

test_module.i(swig接口文件)

%module test_module

%{
#include "../swiginterface.h"
%}

%include "../SwigInterface.h"

%inline %{
  SwigInterface * test;
%}

setup_function(python)

from distutils.core import setup, Extension
setup(name="test_module",
      py_modules=['test_module'],
      ext_modules=[Extension("_test_module",
                     ["test_module.i"],
                     extra_compile_args=["-DSWIG_TYPE_TABLE=test_module"],
                     swig_opts=["-c++", "-py3"],
                  )])

swig_runtime.h中发生问题的函数:

SWIGRUNTIME PyObject* 
SWIG_Python_NewShadowInstance(SwigPyClientData *data, PyObject *swig_this)
{
#if (PY_VERSION_HEX >= 0x02020000)
  PyObject *inst = 0;
  PyObject *newraw = data->newraw;
  if (newraw) {
    inst = PyObject_Call(newraw, data->newargs, NULL);
    if (inst) {
#if !defined(SWIG_PYTHON_SLOW_GETSET_THIS)
      PyObject **dictptr = _PyObject_GetDictPtr(inst);
      if (dictptr != NULL) {
    PyObject *dict = *dictptr;
    if (dict == NULL) {
      dict = PyDict_New();
      *dictptr = dict;
      PyDict_SetItem(dict, SWIG_This(), swig_this);
    }
      }
#else
      PyObject *key = SWIG_This();
      PyObject_SetAttr(inst, key, swig_this);
#endif
    }
  } else {
#if PY_VERSION_HEX >= 0x03000000
    inst = ((PyTypeObject*) data->newargs)->tp_new((PyTypeObject*) data->newargs, Py_None, Py_None); //<----- HERE
    if (inst) {
      PyObject_SetAttr(inst, SWIG_This(), swig_this);
      Py_TYPE(inst)->tp_flags &= ~Py_TPFLAGS_VALID_VERSION_TAG;
    }
#else
    PyObject *dict = PyDict_New();
    if (dict) {
      PyDict_SetItem(dict, SWIG_This(), swig_this);
      inst = PyInstance_NewRaw(data->newargs, dict);
      Py_DECREF(dict);
    }
#endif
  }
  return inst;

我已经用多个版本的SWIG进行了尝试,结果都是一样的。它将模块加载到C ++代码和外部python解释器中都没问题。我该如何调试/解决此问题?

2 个答案:

答案 0 :(得分:0)

要解决此问题,我需要从Python3.7降级到Python3.6

答案 1 :(得分:0)

或升级到具有fix的SWIG 4.0。

相关问题