Заглядывая, как красиво обернуть перечисления в Python с помощью swig, я наткнулся на ответ this.Создание перечисления SWIG в последующем наблюдении на Python
Я пытаюсь создать перечислений так:
#ifndef PYTHON_ENUM
#define PYTHON_ENUM(x) enum x
#endif
PYTHON_ENUM(TestName) {
foo=1,
bar=2
};
PYTHON_ENUM(SomeOtherName) {
woof,
moo
};
Я использую .i файл, как этот
%module test
%{
#include "test.h"
%}
%typemap(constcode) int {
PyObject *val = PyInt_FromLong(($type)($value));
SWIG_Python_SetConstant(d, "$1", val);
const char *name = "$typemap(enum_realname,$1_type)";
PyObject *e = PyDict_GetItemString(d, name);
if (!e) PyDict_SetItemString(d, name, e = PyDict_New());
PyDict_SetItemString(e, "$value", val);
}
#define PYTHON_ENUM(x) \
%typemap(enum_realname) int "x"; \
%pythoncode %{ \
x = _test.x\
%} \
enum x
%include "test.h"
Проблема в том, что это бросает AttributeError: модуль «_test» не имеет атрибута 'TestName' Это связано с тем, что сгенерированный test.py определяет словарь TestName следующим образом:
TestName = _test.testEnum # This should be in the last line
_test.foo_swigconstant(_test)
foo = _test.foo
_test.bar_swigconstant(_test)
bar = _test.bar
В то время, когда вызывается TestName = _test.testEnum
, _test не имеет члена testEnum
и выдает исключение. После запуска либо foo_swigconstant()
, либо bar_swigconstant()
генерируется _test.testEnum
, и TestName = _test.testEnum
не подводит. Таким образом, эта строка должна идти после регистрации значений перечисления. Он работает, если я делаю это вручную, но я должен делать это каждый раз, когда SWIG запускает какую-то проблему. То же самое относится и к другому перечислению. Могу ли я изменить файл интерфейса для этого?
Спасибо за ваш ответ. Я собираю его с VS2012 за то, что стоит, но я не делаю ничего по-другому. Дело в том, что в сгенерированном .py-файле порядок операций приводит к AttributeError. После того, как я играл с кодом, я обнаружил, что, переключая порядок операций, как я упоминал выше, исправляет проблему, но кажется довольно контрпродуктивным, чтобы отредактировать созданный файл py. Я работаю с python 3.5 и SWIG 3.0.7, если это имеет значение. –
Хорошо. Я использую Python 2.7 и SWIG 3.0.7, и я получаю 'TestName = _test.TestName' перед' foo = _test.foo'. Я не получаю никаких записей '_test.bar_swigconstant (_test)'. Он отлично работает для меня. Странный. Вы помните опцию C++? –
Пробовал его здесь, используя VS2013 и SWIG 3.0.8, и он не работает. Я буду сравнивать сгенерированные файлы C++ и .py. Ошибка в сгенерированном коде C++. –