SWIGに、定数セットではなく実際のエンティティとしてC++ enum
を公開することができますので、それらをPythonコードで列挙できますか?SWIGを使用してenumメンバーを列挙する方法
答えて
私は同じ問題に直面しました。 SWIGが間もなくC++ 11のenum class
をサポートすることを願っています。
ここ構造で列挙型を入れてSWIGを説得するハックです:.cpp
コードで
#ifdef SWIG
%rename(MyEnum) MyEnumNS;
#endif
struct MyEnumNS
{
enum Value { Value1, Value2, Value3 };
};
typedef MyEnumNS::Value MyEnum;
あなたが今MyEnum::Value1
を使用する必要がありますし、PythonコードでそれがMyEnum.Value1
です。畳み込まれているにもかかわらず、typedef
は、すべての列挙型を使用する既存のコードを変更する必要がなく、SWIG%名前の変更により、SWIGラッパーで列挙型の名前が同じになります。
def values(enum):
return [(k,v) for k,v in vars(enum).items() if isinstance(v,int)]
それはかなりではない、と私はよりよい解決策を見てみたい:
はPythonでは、あなたは少しのコードで値を列挙することができます。
私はあなたが探しているかなり確信している...
タイプマップ:タイプ処理は、ラッパーコード生成に非常に中心的であるので、SWIGは、それが完全に定義された(または再定義)ユーザーがすることができます。これを行うために、特別な%typemap指示が使用されます。 (SWIG Doc2.0)
ここでタイプマップについて必要な情報はすべて、SWIGのドキュメントに関するリンクです。 http://www.swig.org/Doc2.0/Typemaps.html#Typemaps_nn2
typemapを使用すると、SWIGにC++ enumを必要なPythonオブジェクトに変換するよう指示できます。
@Flexo、tbh、私はタイプマップを知らなかった、私はSWIGを初めて使っていて、彼らはそれをいくつかのより暗い部分のプロジェクトで使っていたが、それは働いていて誰も気にしなかったが、ビット。 – unkulunkulu
私たちはPythonで列挙できるようにすることができます。これは、ラップするC++ヘッダーへの侵入を比較的少なくします。
#ifndef PYTHON_ENUM
#define PYTHON_ENUM(x) enum x
#endif
PYTHON_ENUM(TestName) {
foo=1,
bar=2
};
PYTHON_ENUM(SomeOtherName) {
woof,
moo
};
それは、C++でのごく普通の列挙型であることを拡張しますが、Pythonで列挙メンバーを公開するためのヘッダファイルとして十分なものである:例えば、私たちは、ヘッダファイルを持っている場合。
%typemap(constcode)
を使用すると、私たちはPythonモジュールに列挙型のいくつか追加することができますが、これを行うにはenumの名前を知る必要があります。 SWIGのtypeinfoオブジェクトは、まるでそれがint
の場合と同じです。そのため、私たちはPYTHON_ENUM
マクロでちょっとしたハックを使ってカスタム型マップに列挙型の名前を格納しています。
%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"
これは、キー/値のペアを持つすべての列挙型の中間モジュールにPyDictを作成します。中間モジュールのPyDictを公開されたモジュールに結びつけるために、そこには%pythoncode
グルーがあります。 (私は、_testとしてハードコードされていない以外は、中間モジュールを名前で参照する方法がわかりません - 必要に応じて変更してください)。
これは私がその後、としてそれを使用できるようにすればよい:
Python 2.7.3 (default, Aug 1 2012, 05:16:07)
[GCC 4.6.3] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> import test
>>> print test.SomeOtherName
{'woof': 0, 'moo': 1}
>>> print test.TestName
{'foo': 1, 'bar': 2}
>>>
これは難しいのですが、SWIGの目的が単純なのは、C/C++をスクリプト言語に反映させずに、インターフェイスの生成だけを考えているようです。私はMark Tolonenの解決策をとらなければならないようですが、私はすぐに理解していますが、あなたのことを理解する人はほとんどいません。Dタイプマップで試してみていただきありがとうございます。 – unkulunkulu
@unkulunkulu - 一般的に、SWIGはC(またはC++)でできることすべてを簡単に実行しようとしますが、それを超える逸脱はより困難になる傾向があります。 – Flexo
@Flexo Nice解決策。私はそれを少し拡張して、キーのドット補完をサポートする辞書をインポートし、 'x = _test.x'を' x = dotdict(_test.x) 'に置き換え、'%pythoncode%{dictsからimport { } '' PYTHON_ENUM'マクロの前に。 –
- 1. ENUMライブラリを使用してENUMをモックする方法
- 2. enum名を使用してenum IDを取得する方法
- 3. 明示的キャストなしでstd :: array indexとしてC++ enumクラスの列挙子を使用する方法
- 4. C#:タイプコンバータを使用して列挙型をローカライズする方法
- 5. フィルタを使用して列挙型の列挙列を列挙する
- 6. ReactJSでGraphQLの列挙型からメンバーをリストする方法
- 7. ループでenum-instancesを列挙する
- 8. Typedefing列挙型「メンバー」
- 9. Cで未使用の列挙型メンバーを見つける
- 10. 未使用の列挙型メンバーを見つける
- 11. 表示名enum型のnHibernateで列挙型列をソートする方法
- 12. unixでawkを使用して配列値を列挙する方法
- 13. Dapper.FastCRUDを使用してC#enumをPostgreSQL enumにマップする方法
- 14. enumをスイッチケースで使用する方法
- 15. collection_radio_buttonsでenumを使用する方法
- 16. enumを使用してクラスの型を解決する方法
- 17. enum要素を使用してオブジェクトを作成する方法
- 18. Value Injectorを使用してenumをマップする方法
- 19. Enumの値をEnum.GetValues()よりも列挙する方法がありますか?
- 20. LINQを使用して列挙する正しい方法は何ですか?
- 21. Javadocを使用してEnum値に@linkする方法
- 22. Kotlinでenumを使用してNotNullに変換する方法
- 23. 定数として@Queryでenumを使用する方法
- 24. c#:列挙定数の格納にenumを使用するには?
- 25. System.IO.Directory.GetFilesを使用してファイルとフォルダを再帰的に列挙する方法
- 26. JSDOC3を使用して列挙定数を文書化する方法
- 27. CriteriaBuilderで列挙型を使用してM:Nの関係をクエリする方法
- 28. System.Typeを使用して列挙型からIEnumerableを作成する方法
- 29. SQLを使用してユーザーのリストを列挙する方法は?
- 30. SyntaxWalkerを使用してSyntaxTree内の兄弟ノードを列挙する方法
うん、私はこのような何かを考えていたが、あなたの答えはいくつかのパターンを使用する準備ができて感謝しています。上記の 'sizeof'問題についてもう少し説明してください。私がそれを得ていないので、どんなコードが正確に壊れる可能性があります。 – unkulunkulu
その部分を削除します。実装を見つけようと思っていたときに検討していたものでしたが、再訪しただけで問題にはなりませんでした。 –