C a Python a través de SWIG: no se pueden anular ** los parámetros para mantener su valor

Tengo una interfaz C que se ve así (simplificada):

extern bool Operation(void ** ppData);
extern float GetFieldValue(void* pData);
extern void Cleanup(p);

que se usa de la siguiente manera:

void * p = NULL;
float theAnswer = 0.0f;
if (Operation(&p))
{
   theAnswer = GetFieldValue(p);
   Cleanup(p);
}

Notará que Operation () asigna el búfer p, que GetFieldValue consulta p, y que Cleanup libera p. No tengo ningún control sobre la interfaz C: ese código se usa ampliamente en otros lugares.

Me gustaría llamar a este código desde Python a través deTRAG, pero no pude encontrar ningún buen ejemplo de cómo pasar un puntero a un puntero, y recuperar su valor.

Creo que la forma correcta de hacerlo es mediante el uso de mapas de tipos, por lo que definí una interfaz que automáticamente desreferenciaría p para mí en el lado C:

%typemap(in) void** {
   $1 = (void**)&($input);
}

Sin embargo, no pude hacer funcionar el siguiente código de Python:

import test
p = None
theAnswer = 0.0f
if test.Operation(p):
   theAnswer = test.GetFieldValue(p)
   test.Cleanup(p)

Después de llamar a test.Operation (), p siempre mantuvo su valor inicial de Ninguno.

Cualquier ayuda para descubrir la forma correcta de hacer esto en SWIG sería muy apreciada. De lo contrario, es probable que solo escriba un contenedor C ++ alrededor del código C que evite que Python tenga que lidiar con el puntero. Y luego envolveres envoltura con SWIG. ¡Que alguien me pare

Editar

Gracias a Jorenko, Ahora tengo la siguiente interfaz SWIG:

% module Test 
%typemap (in,numinputs=0) void** (void *temp)
{
    $1 = &temp;
}

%typemap (argout) void**
{
    PyObject *obj = PyCObject_FromVoidPtr(*$1, Cleanup);
    $result = PyTuple_Pack(2, $result, obj);
}
%{
extern bool Operation(void ** ppData); 
extern float GetFieldValue(void *p); 
extern void Cleanup(void *p);
%} 
%inline 
%{ 
    float gfv(void *p){ return GetFieldValue(p);} 
%} 

%typemap (in) void*
{
    if (PyCObject_Check($input))
    {
        $1 = PyCObject_AsVoidPtr($input);
    }
}

El código de Python que usa esta interfaz SWIG es el siguiente:

import test 
success, p = test.Operation()
if success:
   f = test.GetFieldValue(p) # This doesn't work 
   f = test.gvp(p) # This works! 
   test.Cleanup(p) 

Oddly, en el código de Python, test.GetFieldValue (p) devuelve galimatías, pero test.gfv (p) devuelve el valor correcto. He insertado el código de depuración en el mapa de tipos para void *, ¡y ambos tienen el mismo valor de p! La llamada ¿Alguna idea sobre eso?

Actualizar He decidido usar ctypes. Más fácil

Respuestas a la pregunta(2)

Su respuesta a la pregunta