Error al utilizar la callback en Python

Estoy desarrollando un dll que debería usarse en Python. Tengo una función de callback para enviar mis parámetros (definidos en un encabezado separado):

typedef int(*call_nBest)(char **OutList, float* confList, int nB);

Entonces, estoy usando esta callback de esta manera:

 #define TEXT_BUFFER_MAX_SIZE 50 call_nBest nBestList; void Xfunction(const char* aLineThatWillBeConvertedInAList){ char **results; float *confidences; confidences=new float[nBest]; results=new char*[nBest]; for(int i=0; i<nBest; i++) results[i]=new char[TEXT_BUFFER_MAX_SIZE]; MakeLine2List(aLineThatWillBeConvertedInAList,results,confidences); /*At this function I am having the error :(*/ nBestList(results,confidences,nBest); // Passing the values to my callback for(int i=0; i<nBest; i++) delete [] results[i]; delete [] confidences; delete [] results; } 

Y lo estoy exportando de esta manera:

 __declspec(dllexport) int ResultCallback(call_nBest theList){ nBestList = theList; return(0); } 

Probé mi callback primero en otra aplicación de C ++ de esta manera:

 int MyCallback(char **OutLi, float* confLi, int nB){ printf("\n The nB results: %d \n",nB); for(int n=0; n<nB; n++){ std::cout << *(confLi+n) << "\t" << OutLi[n] << "\n"; } return(0); } 

En main() le doy la callback de esta manera:

 ResultCallback(MyCallback); 

y funciona bastante bien. Pero no tengo idea de cómo adaptar esto a Python. He intentado esto:

Nota: He cambiado la última forma, porque resolví algunos errores, pero sigo recibiendo un error. Esta es la forma actual de cómo estoy cargando myDLL

 from ctypes import * def callbackU(OutList,ConList,nB): for i in range(nB): print(OutList[i][0:50]) #I don't know how to print the values return 0 myDLL = cdll.LoadLibrary("MyLibrary.dll") calling = CFUNCTYPE(c_int,POINTER(POINTER(c_char)),POINTER(c_float),c_int) theCall= calling(callbackU) myDLL.ResultCallback(theCall) myDLL.StartProcess(); #In this process the given callback will be invoqued 

ERROR

Y ahora tengo este error:

Excepción no controlada: System.AccessViolationException: se intentó leer o escribir en la memoria protegida. Esto es a menudo una indicación de que otra memoria está dañada. en Xfunction (SByte * aLineThatWillBeConvertedInAList)

Firma del problema:

Problema Nombre del evento: APPCRASH
Nombre de la aplicación: python.exe
Versión de la aplicación: 0.0.0.0
Marca de tiempo de aplicación: 54f9ed12
Nombre del módulo de error: MSVCR100.dll
Versión del módulo de fallo: 10.0.40219.325
Marca de tiempo del módulo de fallo: 10.0.40219.325
Código de excepción: c0000005
Offset de excepción: 00001ed7
Versión del SO: 6.3.9600.2.0.0.256.4
ID local: 1033
Información adicional 1: 5861
Información adicional 2: 5861822e1919d7c014bbb064c64908b2
Información adicional 3: a10f
Información adicional 4: a10ff7d2bb2516fdc753f9c34fc3b069

Cosas que he hecho y son casi lo que quiero:

Primero cambié la función de callback de Python para este:

 def callbackU(OutList,ConList,nB): for i in range(nB): print(i) return 0 

Todo funciona sin error y puedo ver esto en la consola (en este caso, nB era 10 ):

 0 1 ... 9 

Segundo, cambié la función como esta:

 def callbackU(OutList,ConList,nB): for i in range(nB): print (cast(OutList,c_char_p)) return 0 

y, oh sorpresa, esto solo imprime la primera palabra de la lista (nB veces)

¿Quieres algo como esto?

 def callbackU(OutList, ConList, nB): for i in range(nB): print("{}\t{}".format(ConList[i], cast(OutList[i], c_char_p))) return 0 

Por lo que entiendo, solo está intentando hacer coincidir la salida de su función de callbackU Python con su función MyCallback C ++.

Python tiene una variedad de funciones de formato de cadena que pueden ser confusas al principio, pero rinde homenaje al formato de cadena printf .

Dado que OutList tiene el tipo LP_LP_c_char (puntero a puntero de c_char , vs “NULL terminated char *c_char_p ), es mejor que lo conviertan en un tipo de datos de Python nativo como:

 def callbackU(OutList, ConList, nB): for i in range(nB): out_list_item = cast(OutList[i], c_char_p).value print("{}\t{}".format(ConList[i], out_list_item)) return 0