Массив структур в структурированный массив NumPy: np.ctypeslib.as_array из ndpointer - PullRequest
0 голосов
/ 24 декабря 2018

Я пытаюсь вызвать функцию C, которая принимает указатель на указатель и перенаправляет его во внутренне размещенный одномерный массив, что-то вроде этой строки:

typedef myStruct {
    const char* name;
    int status;
} myStruct;

int foo(const myStruct** array, size_t* size);

Я пытаюсь обернутьэто с Python и NumPy, и получить массив NumPy, который оборачивает эту внутреннюю память (только для чтения).

У меня есть следующее:

arr = np.ctypeslib.ndpointer(dtype=np.dtype([('name', np.intp),
                                             ('status', np.int)]))()
size = ct.c_size_t()
_call('foo', ct.byref(arr), ct.byref(size))
arr = np.ctypeslib.as_array(arr, shape=(size.value,))
arr.flags.writeable = False # not our memory!

Где _call()обертка, которая проверяет возвращаемое значение.

Я получаю следующее:

ValueError: '<P' is not a valid PEP 3118 buffer format string

по вызову as_array().Что я делаю не так?


РЕДАКТИРОВАТЬ: Моя цель здесь состоит в том, чтобы прочитать данные в виде структурированного массива NumPy, так как я думаю, что это лучший способ описать массив структур Cв питоне.

1 Ответ

0 голосов
/ 07 января 2019

Возможно, это можно рассматривать как ошибку в ndpointer - проблема в том, что as_array проверяет, является ли его аргумент указателем, но этот тест не проходит для ndpointer, и numpy пытается создать массив, содержащий одинуказатель (который терпит неудачу, потому что у numpy нет типа указателя).

Вы можете просто отлично справиться, вообще не используя numpy:

class myStruct(ctypes.Structure):
    _fields_ = [
        ('name', ctypes.c_char_p),
        ('status', ctypes.c_int),
    ]

arr = ctypes.POINTER(myStruct)()
size = ct.c_size_t()
_call('foo', ct.byref(arr), ct.byref(size))

# convert from `myStruct*` to `myStruct[size]`
arr = ctypes.cast(arr, ctypes.POINTER(myStruct * size.value)).contents

arr теперь является массивом ctypes.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...