es.davy.ai

Preguntas y respuestas de programación confiables

¿Tienes una pregunta?

Si tienes alguna pregunta, puedes hacerla a continuación o ingresar lo que estás buscando.

SWIG typemap para convertir una matriz 2D en una lista de Python

Esto es un siguiente nivel de esta pregunta. Necesito convertir una matriz de caracteres C de 2 dimensiones en una lista de Python.

Lado de Python

device_info = getInfoFromCpp()
print(device_info.angles)
for angle in device_info.angles:
  print("Ángulo: " + angle)

Error

<swig object="" of="" type="" 'char="" (*)[maxstringlength]'="" at="" 0x000000d8b2710330="">
Error de ejecución: el objeto 'SwigPyObject' no es iterable

Encabezado de C++

struct DeviceInformation {
  static const int MaxStringLength= 200;
  static const int MaxNumberOfAngles= 5;

  char serialNumber[MaxStringLength];
  char angles[MaxNumberOfAngles][MaxStringLength];
};

Basado en la respuesta de @MarkTolonen aquí, intento lo siguiente con los “typemaps”, pero sin resultado.
c++
// %typemap(out) char [ANY] %{
// %typemap(out) char (*)[ANY] %{
%typemap(out) char [ANY][ANY] %{
PyObject *pyArray = PyList_New(5);
for (uint8_t i = 0; i < 5; ++i) {
PyObject *pyString = PyString_FromString(reinterpret_cast<char*>($1[i]));
PyList_SetItem(pyArray, i, pyString);
}
$result = pyArray;
}
</char*>

Tags:  , , , ,

Answer

  1. Avatar for davy.ai

    El mensaje de error indica que el objeto SwigPyObject devuelto por getInfoFromCpp() no es iterable. Esto sugiere que el mapeo de tipo SWIG para el miembro angles de la estructura DeviceInformation puede no estar funcionando correctamente.

    Según el código de mapeo de tipo proporcionado, parece que estás intentando utilizar la directiva %typemap(out) para convertir la matriz char[5][200] en una lista de cadenas de Python. Sin embargo, el mapeo de tipo parece estar incompleto, ya que incluye líneas comentadas para %typemap(out) para char*[ANY] y char (*)[ANY], pero ninguna de estas se utiliza realmente.

    Un problema con el mapeo de tipo actual es que asume que la matriz angles siempre tiene 5 entradas. Si este no es el caso, el código no funcionará correctamente. Puedes solucionar esto reemplazando el valor codificado en duro 5 por MaxNumberOfAngles, que es la constante definida en la estructura DeviceInformation.

    Aquí tienes una versión revisada del mapeo de tipo que debería funcionar:

    %typemap(out) char [MaxNumberOfAngles][MaxStringLength] {
        PyObject *pyArray = PyList_New(MaxNumberOfAngles);
        for (uint8_t i = 0; i < MaxNumberOfAngles; ++i) {
            PyObject *pyString = PyUnicode_FromString($1[i]);
            PyList_SetItem(pyArray, i, pyString);
        }
        $result = pyArray;
    }
    

    Este mapeo de tipo utiliza las constantes MaxNumberOfAngles y MaxStringLength definidas en DeviceInformation, por lo que debería manejar matrices de cualquier tamaño. También utiliza PyUnicode_FromString en lugar de PyString_FromString, que es la función correcta para usar en Python 3 (aunque PyString_FromString debería seguir funcionando en Python 2).

    Con este mapeo de tipo en su lugar, el miembro angles se debería convertir en una lista de cadenas de Python cuando llames a getInfoFromCpp() y accedas al atributo angles en Python.

Comments are closed.