2014-07-09 2 views
1

나는 C로 파이썬 모듈을 작성하는 것에 젖음을 느꼈다. 나는 두 점의 표준을 계산하는 간단한 예제로 시작했다. 코드는C로 쓰여진 파이썬 모듈로 전달되는 인수

_norm.c

#include <Python.h> 
#include "norm.h" 

static char module_docstring[] = 
    "This module provides an interface for computing the norm using C."; 
static char norm_docstring[] = 
    "Calculate the norm between two points"; 
static char norm2_docstring[] = 
    "Calculate the square norm between two points. For efficiency."; 

static PyObject *norm_norm(PyObject *self, PyObject *args); 

static PyObject *norm_norm2(PyObject *self, PyObject *args); 

static PyMethodDef module_methods[] = { 
    {"norm", norm_norm, METH_VARARGS, norm_docstring}, 
    {"norm2", norm_norm2, METH_VARARGS, norm2_docstring}, 
    {NULL, NULL, 0, NULL} 
}; 

PyMODINIT_FUNC init_norm(void) { 
    PyObject *m = Py_InitModule3("_norm", module_methods, module_docstring); 
    if (m == NULL) 
     return; 
} 

static PyObject *norm_norm(PyObject *self, PyObject *args) { 
    double x1, y1, x2, y2; 
    /* Parse the input tuple */ 
    if (!PyArg_ParseTuple(args, "ddOOO", &x1, &y1, &x2, &y2)) 
     return NULL; 

/* Call the external C function to compute the norm. */ 
double value = norm(x1, y1, x2, y2); 

if (value < 0.0) { 
    PyErr_SetString(PyExc_RuntimeError, 
        "Norm returned an impossible value."); 
} 
PyObject *ret = Py_BuildValue("d", value); 
return ret; 
} 

norm.c, 다음과 같습니다

#include <math.h> 

long double norm2(long double x1, long double y1, long double x2, long double y2) { 
    long double xd = x2 - x1; 
    long double yd = y2 - y1; 
    return xd * xd + yd * yd; 
} 

long double norm(long double x1, long double y1, long double x2, long double y2) { 
    return sqrt(norm2(x1, y1, x2, y2)); 
} 

setup.py

from distutils.core import setup, Extension 

setup(
    ext_modules=[Extension("_norm", ["_norm.c", "norm.c"])] 
) 

이렇게 패키지를 만들었습니다.

python setup.py build_ext --inplace 

그리고 문제없이 컴파일됩니다. 그러나 그것을 사용하려고하면 인수의 수에 대한 오류가 발생합니다.

>>> import _norm 
>>> _norm.norm(1,2,5,6) 
Traceback (most recent call last): 
File "<stdin>", line 1, in <module> 
TypeError: function takes exactly 5 arguments (4 given) 

나는 그것이 * 자기 전달됩니다 있기 때문에)의 PyObject *의 norm_norm (의 선언을 함께 할 수있는 뭔가가있을 것 같아요,하지만 난에 모듈에 전달하는 인자에 영향을해야합니다 있는지 확실하지 않습니다 사물의 파이썬 측면. 나는 어떤 도움이나 제안을 주시면 감사하겠습니다.

답변

2

PyArg_ParseTuple의 형식 문자열에 문제가 있습니다. 4 개의 double 인수를 추출하려하지만 형식 문자열은 두 개의 double 인수와 임의의 3 개의 Python 객체 ("ddOOO")에 대한 것입니다.

올바른 형식 문자열은 수행하려는 작업에 대해 "dddd"여야합니다. 이

경우 (! PyArg_ParseTuple (인수, "ddOOO"& 1 개, & Y1, & X2, & Y2))

경우에 (! PyArg_ParseTuple 변경 (args, "dddd", &x1, &y1, &x2, &y2))

+0

아, 감사합니다! 그것이 문제였습니다. – Alexa