Pickle Cython Class con punteros C

Estoy tratando de escribir un__reduce__() método para una clase de cython que contiene punteros en C pero que hasta ahora ha encontrado muy poca información sobre la mejor manera de hacerlo. Hay muchos ejemplos de cómo escribir correctamente un__reduce__() método cuando se usan matrices numpy como datos de miembros. Me gustaría mantenerme alejado de las matrices de Numpy, ya que parecen estar siempre almacenadas como objetos de Python y requieren llamadas hacia y desde la API de Python. Vengo de un fondo C, así que me siento muy cómodo trabajando con la memoria manualmente usando llamadas amalloc() yfree() y estoy tratando de mantener la interacción de python al mínimo absoluto.

Sin embargo, me he encontrado con un problema. Necesito usar algo equivalente acopy.deepcopy() en la clase que estoy creando, desde el script de Python donde finalmente se usará. He descubierto que la única buena manera de hacer esto es implementar el protocolo pickle para la clase implementando un__reduce__() método. Esto es trivial con la mayoría de los objetos primitivos u python. Sin embargo, tengo una pérdida absoluta de cómo hacer esto para las matrices C asignadas dinámicamente. Obviamente, no puedo devolver el puntero en sí, ya que la memoria subyacente habrá desaparecido para cuando se reconstruya el objeto, entonces, ¿cuál es la mejor manera de hacer esto? Estoy seguro de que esto requerirá la modificación de ambos__reduce__() método, así como uno o ambos__init__() métodos

He leído la documentación de Python sobre los tipos de extensión de decapadoencontrado aquí así como casi cualquier otra cuestión de desbordamiento de pila sobre cómo elegir clases de cython comoesta pregunta.

Una versión condensada de mi clase se parece a esto:

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))

Respuestas a la pregunta(1)

Su respuesta a la pregunta