I am learning C library wrapping in cython. I compiled a couple of simple C function and header files using cython and now am trying to run another example which is more complicated one than previous examples.
I downloaded very first version of Sundials C source code (IDA module only) and made a *.lib using VS 2019. Now I am trying to wrap just one function to see how it works. However I couldn't figure out how to properly wrap a function with void * argument to cython function. Here is the example.
The ida_mem
is void pointer to an address of an allocated memory from C malloc
function. How should I
call IDACalcIC
function at the bottom with correct pointer argument ?
IDA.pyx file
cdef extern from "ida.h":
ctypedef double real;
ctypedef int integer;
int IDACalcIC(void *ida_mem, int icopt, real tout1, real epicfac, int maxnh, int maxnj, int maxnit, int lsoff, real steptol)
cpdef CyIDACalcIC(void *ida_mem, icopt, tout1, epicfac, maxnh, maxnj, maxnit, lsoff, steptol):
cdef int icopt
cdef int maxnh
cdef int maxnj
cdef int maxnit
cdef int lsoff
cdef real tout1
cdef real epicfac
cdef real steptol
IDACalcIC(ida_mem (?), icopt, tout1, epicfac, maxnh, maxnj, maxnit, lsoff, steptol)
The void pointer you're passing is is just working memory for the solver, which you need to allocate yourself prior to calling other functions that might use it, typically the solving function. This is typical in C where you manage memory yourself, but quite alien if in Python.
You're looking to do the Cython equivalent of this code in pySundials (lines 94-105 and 147-153)
You can allocate the memory yourself with a call to IDACreate, and then pass the returned value into IDACalcIC, although I would suggest using wrapper classes similar to those below to do it, which will make using the C library feel more natural to python user's.
The
IdaMemObj
class exists to wrap the allocated memory as returned by the C functionIDACreate
in the form of avoid *
. It uses__del__
to ensure the memory allocated is freed (dealloacted) when the python object goes out of scope and is garbage collected.