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. C#:タイプコンバータを使用して列挙型をローカライズする方法
- 3. ループでenum-instancesを列挙する
- 4. 未使用の列挙型メンバーを見つける
- 5. enumを使用してクラスの型を解決する方法
- 6. collection_radio_buttonsでenumを使用する方法
- 7. enumをスイッチケースで使用する方法
- 8. LINQを使用して列挙する正しい方法は何ですか?
- 9. Javadocを使用してEnum値に@linkする方法
- 10. JSDOC3を使用して列挙定数を文書化する方法
- 11. CriteriaBuilderで列挙型を使用してM:Nの関係をクエリする方法
- 12. System.IO.Directory.GetFilesを使用してファイルとフォルダを再帰的に列挙する方法
- 13. SWIGを使って配列とやりとりする正しい方法
- 14. c#:列挙定数の格納にenumを使用するには?
- 15. Java ResultSetとPreparedStatementを使用してmySQL列挙型フィールドにアクセスする方法
- 16. 高速列挙ARCを使用して
- 17. 列挙型を使用してビット配列をインデックス化する
- 18. SWIGを使用してSockaddr_in C構造体をJavaにマップする方法
- 19. Visual Studio 2010からSWIGを使用してDLLを作成する方法
- 20. NHibernateの列挙型プロパティでICriteriaを使用する方法
- 21. JavascriptでC#列挙型を使用する方法
- 22. Java:配列参照として列挙型を使用する
- 23. 列の列挙を使用したLINQテーブルの列挙
- 24. なぜ列挙型解決演算子を使用してenumにアクセスできるのですか?
- 25. ENUMをビットマップとして使用してCで検証する方法
- 26. DataGridView:列挙型を使用するComboBox列。デザイナーからセットアップする方法?
- 27. Javaで列挙型の値をすべて取得する方法は? (特定のEnumを知らない)
- 28. 異なる列挙からのenum値を保持するフィールド
- 29. PHPリフレクションを使用して列挙を作成する
- 30. 列挙型を使用してテンプレートを特殊化する
うん、私はこのような何かを考えていたが、あなたの答えはいくつかのパターンを使用する準備ができて感謝しています。上記の 'sizeof'問題についてもう少し説明してください。私がそれを得ていないので、どんなコードが正確に壊れる可能性があります。 – unkulunkulu
その部分を削除します。実装を見つけようと思っていたときに検討していたものでしたが、再訪しただけで問題にはなりませんでした。 –