2017-04-07 15 views
1

Python에서 C 모듈을 통합하고자하므로 인터페이스가 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]) 

파이썬 측면 :

from SummaLogic import getSumma 

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

내가 터미널에서 시작할 때 잘 보이지만, - 아무 일도 발생하지 않습니다, 어떤 활동도하지 않고 매달려 있습니다. 나는 무엇을 놓칠 수 있습니까?

답변

1

이것은 PyList_Size으로 귀결되며 오류가 없는지 확인하십시오.

아마도 numsargs이 아닌 인수에 사용하고 싶을 것입니다. 당신은 args에 사용 매우 흥미로운 일이 일어난 단 :

  • argstuple입니다
  • 따라서 PyList_Size 실패와 -1
  • 을 반환 아마 매우 결과 부호 size_t에 던져졌다 -1 그 아마도 2**64-1
  • 따라서 2**64-1 개 항목을 반복하는 데 꽤 오랜 시간이 걸리기 때문에 "매우 긴 시간"이 반복됩니다. 모든 out-of-bound 메모리 액세스). 그렇지 않으면 당신이 정의를 많이 얻을 것이다

    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 */ 
    

    당신이 모든 파이썬 C API 함수 호출 후에 그들에 대한 오류 조건이 무엇인지 확인하고 테스트해야하지만 :

빠른 수정 사용하는 것 행동. 또한 int32_t (PyInt_AsLonglong을 반환하므로 이상한 캐스팅 오류가 발생할 수 있습니다.), size_t, ... 및 typedef PyObject* Py; 대신 정의 된 리턴 유형을 사용하면 C 확장자를 정기적으로 작성하는 사람에게는 매우 까다로운 작업이됩니다.

+0

매우 감사드립니다! 당신은 저를 많은 시간을 절약했습니다.) – errfrom

+0

@errfrom 환영합니다 :) gdb를 사용하여 디버깅하기 쉽도록 스크립트를 실행할 때 세그먼트 화 오류가 발생했습니다. – MSeifert