2011-11-02 4 views
2

組み込みのPythonシナリオでは、PyArg_ParseTupleAndKeywordsを使用してPython(バージョン> = 3 .x)からデータを受け取り、C++アプリケーションで使用します。我々は全部のクラッシュ(本当に、それが返されます(whatever(foo="a", bar="b", baz="c")のようなPythonのコールを発行するなど)2は、予想以上のパラメータを渡すと、しかしPyArg_ParseTupleAndKeywordsを使用する際に関連性のないパラメータを除外する

PyObject* whatever(PyObject *self, PyObject *args, PyObject *keywds) { 
    .... 
    static char* kwlist[] = { "foo", "bar", NULL }; 
    ... 
if(!PyArg_ParseTupleAndKeywords(args, keywds, ..., kwlist, ...)) 
    { 
     ...bail out 

:私たちは同様のセットアップを持っている瞬間

エラーですが、それはここの範囲を超えています)。

このようなシナリオは避けてください。 だけをkwlistのパラメータで解析し、それ以外のものは無視するといいでしょう。それを行う最善の方法は何ですか?

kwlistdictに変換してから、PyDict_Mergeなどで操作してください。

答えて

1

最後に、私たちは以下のようにそれを解決:

(誰も答えていないので、私は自分の質問に答えるんだ、と私はそれが将来的に他の誰かに価値があるかもしれないと思います)。

PyObject* whatever(PyObject *self, PyObject *args, PyObject *incoming_keywds) 
{ 

    static char* kwlist[] = { "foo", "bar", NULL }; 

    PyObject* keywds = PyDict_New(); 
    /** 
    * The following routine returns a subset of the incoming dictionary 'incoming_keywds' 
    * containing only the keys allowed in the list 'kwlist' 
    */ 
    for (int i = 0 ; kwlist[i] != NULL ; i++) 
    { 
     char* key = kwlist[i]; 
     PyObject *single_key = Py_BuildValue("s", key); 
     if (PyDict_Contains(incoming_keywds, single_key)) 
     { 
      // not checking for NULL as GetItem return value since 
      // we already checked above if the dict contains key 'single_key' 
      if (PyDict_SetItem(keywds, single_key, PyDict_GetItem(incoming_keywds, single_key)) < 0) 
      { 
       /* error */ 
      } 
     } 
     Py_DECREF(single_key); 
    } 
    /** end */ 
関連する問題