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:

  • args tuple,
  • therefore pylist_size failed , returned -1
  • that -1 cast unsigned size_t resulted in huge number, 2**64-1
  • therefore iteration runs "very long time" because takes quite while iterate on 2**64-1 items (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

Popular posts from this blog

How to understand 2 main() functions after using uftrace to profile the C++ program? -

c# - Update a combobox from a presenter (MVP) -

How to put a lock and transaction on table using spring 4 or above using jdbcTemplate and annotations like @Transactional? -