2017-04-07 9 views
1

CモジュールをPythonに統合したいので、私の選択はインタフェースPython.hになりました。すべてがエラーや警告なしでコンパイルされているので、問題の内容を理解できません。Python/C API - 結果は表示されません

C側:

#include <python3.5m/Python.h> 
... 
#define PyInt_AsLong(x) (PyLong_AsLong((x))) 
typedef PyObject* Py; 

static Py getSumma(Py self, Py args){ 
    Py nums; 
    if (!PyArg_ParseTuple(args, "O", &nums)){ 
    return NULL; 
    } 
    size_t numsAmount = PyList_Size(args); 
    int32_t summa = 0; 

    for (size_t i = 0; i < numsAmount; i++){ 
    Py temp = PyList_GetItem(nums, i); 
    int32_t num = PyInt_AsLong(temp); 
    summa += num; 
    } 
    return Py_BuildValue("l", summa); 
} 

static PyMethodDef moduleMethods[] = { 
    {"getSumma", (PyCFunction)getSumma, METH_VARARGS, NULL}, 
    {NULL, NULL, 0, NULL} 
}; 

static PyModuleDef SummaLogic = { 
    PyModuleDef_HEAD_INIT, 
    "SummaLogic", 
    "", 
    -1, 
    moduleMethods 
}; 

PyMODINIT_FUNC PyInit_SummaLogic(void){ 
    return PyModule_Create(&SummaLogic); 
} 

setup.py:

from distutils.core import setup, Extension 

SummaLogic = Extension("SummaLogic", sources=['SummaLogic.c']) 
setup(ext_modules=[SummaLogic]) 

のPython側:

from SummaLogic import getSumma 

if __name__ == "__main__": 
    a = [1, 2, 3] 
    b = getSumma(a) 
    print(b) 

私はターミナルでそれを起動したときにそれが正しいようだが、 - 何も起こりません、何の活動もせずにぶら下がっています。何が恋しいの?

答えて

1

これはPyList_Sizeになっており、エラーがないかどうかは確認していません。

おそらくnumsではargsではなく、それを引数として使用したかったでしょう。しかし、あなたはargsに使用し、非常に興味深いことが起こった:

  • argsのでtuple
  • PyList_Sizeは、おそらく非常に結果の符号なしsize_tにキャストされた-1ことを失敗したと-1
  • を返されますおそらく2**64-1
  • だから、2**64-1アイテムを繰り返し処理するのにかなりの時間がかかるので、あなたの繰り返しは「非常に長い時間」実行されます。すべてのアウト・オブ・バウンド・メモリ・アクセス)。クイックフィックスを使用することです

Py_ssize_t listlength = PyList_Size(nums); /* nums instead of args */ 
if (listlength == -1) { /* check for errors */ 
    return NULL; 
} 
size_t numsAmount = (size_t)listlength /* cast to size_t only after you checked for errors */ 

を使用すると、すべてのPythonのC API関数の呼び出し後にエラー条件が何であるかをチェックし、彼らのためにテストする必要がありしかしそうしないと、未定義の多くを得るでしょう行動。また、int32_tPyInt_AsLongが返ってくるのでlongが返されるので、そこに奇妙なキャストエラーが出るかもしれません)の定義された戻り値の型に固執します。 ... typedef PyObject* Py;は、C拡張を定期的に書く人にとっては本当に面倒です。

+0

非常に感謝します!あなたは私に多くの時間を節約しました) – errfrom

+0

@errfrom歓迎:) gdbを使ってデバッグするのは非常に簡単だったので、スクリプトを実行すると実際にセグメンテーション違反が発生しました。 – MSeifert

関連する問題