Использование 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. Как мне отладить / исправить эту проблему?