I am trying to write a __reduce__()
method for a cython class that contains C pointers but have so far found very little information on the best way to go about doing this. There are tons of examples around for how to properly write a __reduce__()
method when using numpy arrays as member data. I'd like to stay away from Numpy arrays as they seem to always be stored as python objects and require calls to and from the python API. I come from a C background so I am very comfortable working with memory manually using calls to malloc()
and free()
and am trying to keep python interaction to an absolute minimum.
However I have run into a problem. I have a need to use something equivalent to copy.deepcopy()
on the class I am creating, from the Python script where it will ultimately be used. I have found that the only good way to do this is to implement the pickle protocol for the class by implementing a __reduce__()
method. This is trivial with most primitives or python objects. However I am at an absolute loss for how to go about doing this for dynamically allocated C arrays. Obviously I can't return the pointer itself as the underlying memory will have disappeared by the time the object is reconstructed, so what's the best way to do this? I'm sure this will require modification of both the __reduce__()
method as well as one or both of the __init__()
methods.
I have read the python documentation on pickling extension types found here as well as just about every other question of stack overflow about picking cython classes such as this question.
A condensed version of my class looks something like this:
cdef class Bin:
cdef int* job_ids
cdef int* jobs
cdef int primitive_data
def __cinit__(self):
self.job_ids = <int*>malloc(40 * sizeof(int))
self.jobs = <int*>malloc(40 * sizeof(int))
def __init__(self, int val):
self.primitive_data = val
def __dealloc__(self):
free(job_ids)
free(jobs)
def __reduce__(self):
return (self.__class__, (self.primitive_data))