Python/C API - The result is not displayed -
i integrate c modules in python, choice fell on interface python.h. compiled without errors , warnings, can not understand problem is.
c side:
#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; (size_t = 0; < 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 side:
from summalogic import getsumma if __name__ == "__main__": = [1, 2, 3] b = getsumma(a) print(b) it seems right, when start in terminal - nothing happens, hanging without activity. miss?
it boils down pylist_size , don't check errors there.
you wanted use on nums, not args argument. used on args , interesting thing happened:
argstuple,- therefore
pylist_sizefailed , returned-1 - that
-1cast unsignedsize_tresulted in huge number,2**64-1 - therefore iteration runs "very long time" because takes quite while iterate on
2**64-1items (apart out-of-bound memory accesses).
the quick fix use:
py_ssize_t listlength = pylist_size(nums); /* nums instead of args */ if (listlength == -1) { /* check errors */ return null; } size_t numsamount = (size_t)listlength /* cast size_t after checked errors */ however should check error conditions , test them after every python c api function call otherwise you'll lot of undefined behaviours. stick defined return types instead of int32_t (pyint_aslong returns long might weird casting errors there well!), size_t, ... , typedef pyobject* py; makes things tricky regularly writes c extensions.
Comments
Post a Comment