2016-07-18 16 views
1

CPythonという拡張子をCで書かれたライブラリの上に書きましたが、initメソッドで例外を発生させる方法を見つけることができませんでした。だから、私はそれを分割し、基本的に、コンストラクタは、オブジェクトに属性を保存し、initメソッドmr.initialize()を呼び出す必要があります。CPythonモジュールのinitメソッドで例外を発生させる方法

static int libzihc_MRLoader_init(libzihc_MRLoader *self, PyObject *args, PyObject *kwds) { 
    double error_rate; 
    const char *in; 
    unsigned int capacity; 

    static char *kwlist[] = {"in", NULL}; 
    if (!PyArg_ParseTupleAndKeywords(args, kwds, "s", kwlist, &in)) { 
     return -1; 
    } 
    if (self->dataPath) { 
     free(self->dataPath); 
    } 
    self->dataPath = malloc(sizeof(char)*(strlen(in)+1)); 
    if (self->dataPath) { 
     strcpy(self->dataPath, in); 
    } else { 
     PyErr_NoMemory(); 
    } 
    return 0; 
} 

そしてそうのような追加initializeメソッド:

ここに私の現在のコードですが、私は少し醜いこの方法を見つけて、私はコンストラクタでValueError例外を発生させるための解決策を見つけたい

CPythonドキュメントから
static PyObject* initialize(libzihc_MRLoader *self, PyObject *args, PyObject *kwds) { 
    const char * msgError = NULL; 
    int status = openRes(self->dataPath, &(self->ienaKey), &msgError); 

    if(status != 0) { 
     PyErr_SetString(PyExc_ValueError, msgError); 
     printf("openRes returns %d\n", status); 
     return (PyObject *) NULL; 
    } 
    return Py_BuildValue("i", status); 
} 

、あなたはインタプリタはあなたが私が​​を使用私の場合は例外を発生させるために使用される方法のいずれかを呼び出す必要が例外を発生させ、そしてを返すようにしたい場合。この場合

CPythonでinitメソッドをstatic intでなければならないので、私はnullを返すことはできません、私は、しかし、returnステートメントを削除しなかった、私はstdoutで例外を見ましたが、通訳が止まりませんでした。

どうすればこの問題を解決できますか?

答えて

0

libzihc_MRLoader_initに負の値、通常は-1を返して、Pythonがそれをキャッチし、例外が設定されているかどうかを調べて実行を終了する必要があります。少なくとも、それは、オブジェクト__init__メソッド呼び出した後のためtype_callチェック何:エラーが発生しているのであれば

type = obj->ob_type; 
    if (PyType_HasFeature(type, Py_TPFLAGS_HAVE_CLASS) && 
     type->tp_init != NULL && 
     type->tp_init(obj, args, kwds) < 0) { // if res < 0 returns NULL 
     Py_DECREF(obj); 
     obj = NULL; 
    } 

は、あなたの特定のケースでは、あなたは、libzihc_MRLoader_initinitializeからコードを移動することができ、返却-1の代わりに、 nullに送信してください。

+0

あなたの返答に感謝します。しかし、私が 'null'を返さない場合、インタプリタは例外をキャッチせず、実行を停止しません。 –

+0

@ e-nouri 'initialize'ではなく' null'を返すことができない 'libzihc_MRLoader_init'に' -1'を返すことを提案しました。 –

+0

ありがとうございました、私はここに投稿する前にそれを試してみるべきですが、PyErr_ *関数を呼び出した後、インタープリタを停止する方法についてはあまり明確ではありませんでした。 –

関連する問題