C para Python via SWIG: não é possível obter parâmetros ** nulos para manter seu valor

Eu tenho uma interface C com esta aparência (simplificada):

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

que é usado da seguinte maneira:

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

Você observará que Operation () aloca o buffer p, que GetFieldValue consulta p e que Cleanup libera p. Não tenho controle sobre a interface C - esse código é amplamente usado em outros lugare

Gostaria de chamar esse código do Python viaGOL, mas não consegui encontrar bons exemplos de como passar um ponteiro para outro - e recuperar seu valo

Acho que a maneira correta de fazer isso é usando mapas de tipo, por isso defini uma interface que desreferiria automaticamente p para mim no lado C:

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

No entanto, não foi possível obter o seguinte código python para funcionar:

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

Após chamar test.Operation (), p sempre manteve seu valor inicial de None.

Qualquer ajuda para descobrir a maneira correta de fazer isso no SWIG seria muito apreciada. Caso contrário, provavelmente escreverei um wrapper C ++ em torno do código C que impede o Python de lidar com o ponteiro. E depois enroleaquel wrapper com SWIG. Alguém me pare

Editar

Graças a Jorenko, Agora tenho a seguinte interface 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);
    }
}

O código python que usa essa interface SWIG é o seguinte:

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) 

Odly, no código python, test.GetFieldValue (p) retorna sem sentido, mas test.gfv (p) retorna o valor correto. Inseri o código de depuração no mapa de tipos para void * e ambos têm o mesmo valor de p! A chamada Alguma idéia sobre isso?

Atualizar Decidi usar ctypes. Muito facil

questionAnswers(2)

yourAnswerToTheQuestion