swigを使用してPythonでenumをうまくラップする方法を調べると、私はthisの答えに出くわしました。SWIGの列挙型をPythonのフォローアップで作成
私はそのような列挙型を作成しようとしています:モジュールの_test 'には属性がありません:
#ifndef PYTHON_ENUM
#define PYTHON_ENUM(x) enum x
#endif
PYTHON_ENUM(TestName) {
foo=1,
bar=2
};
PYTHON_ENUM(SomeOtherName) {
woof,
moo
};
は、私はこの問題は、これははAttributeErrorをスローすることをあること
%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"
などの.iファイルを使用します'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
が失敗しません。したがって、この行はenum値の登録後に行かなければなりません。私が手作業で行うと機能しますが、SWIGが走るたびにそれをやらなければなりません。他の列挙も同様です。それに合わせてインタフェースファイルを変更することはできますか?
あなたの答えをありがとう。私はそれを価値あるものとしてVS2012でコンパイルしていますが、私は何か別のことをやっていません。問題は、生成された.pyファイルで、操作の順序がAttributeErrorになることです。コードでaroungをプレイした後、上で述べたように操作の順序を変えることで問題が解決されることがわかりましたが、生成されたpyファイルを編集しなければならないのはかなり生産的です。私はpython 3.5とSWIG 3.0.7で問題があれば作業しています。 –
私はPython 2.7とSWIG 3.0.7を使い、 'foo = _test.foo'の前に' TestName = _test.TestName'を出します。私は '_test.bar_swigconstant(_test)'エントリを取得しません。それは私のために完璧に動作します。奇妙な。あなたはC++オプションを覚えていましたか? –
VS2013とSWIG 3.0.8を使って仕事場で試してみましたが、動作していません。生成されたC++と.pyファイルを比較します。エラーは、生成されたC++コードにあります。 –