PyBytes_FromString отличается порядком байтов - PullRequest
0 голосов
/ 30 апреля 2020

У меня есть python -обернутый объект C ++, базовыми данными которого является контейнер std::vector<T>, представляющий биты. У меня есть функция, которая записывает эти биты в объект PyBytes. Если порядок байтов тот же, то проблем нет. Однако, если я буду sh записывать байты с другим порядком байтов, то мне нужно будет поменять биты (или поменять байты) каждое слово.

В идеале я мог бы передать итератор вывода конструктору PyBytes_FromString, где оператор вывода просто преобразует порядковый номер каждого слова. Это будет O(1) дополнительная память, которая является целью.

Менее в идеале я мог бы каким-то образом создать пустой объект PyBytes, вручную создать массив char с разным порядком байтов и каким-то образом назначить его объекту PyBytes (в основном, переопределить конструкторы PyBytes ). Это также будет O(1) дополнительная память. К сожалению, способ сделать это - использовать _PyBytes_FromSize, но это не доступно в API.

Текущий способ сделать это - создать полную копию перевернутых слов, просто затем скопировать это представление по отношению к представлению объектов PyBytes.

Я думаю, что второй вариант является наиболее практичным способом сделать это, но единственный способ увидеть, как работает, - это просто скопировать функцию _PyBytes_FromSize в мой источник код, который кажется взломанным. Я новичок в python - C API и мне интересно, есть ли более чистый способ сделать это.

1 Ответ

0 голосов
/ 03 мая 2020

PyBytes_FromStringAndSize позволяет передать NULL в качестве первого аргумента, в этом случае он возвращает неинициализированный объект байтов (который вы можете редактировать). Это на самом деле просто эквивалентно _PyBytes_FromSize и позволит вам сделать второй вариант.


Если вы хотите вместо этого использовать опцию «output iterator», то решением будет вызвать PyBytes_Type:

 PyObject *result = PyObject_CallFunctionObjArgs((PyObject*)&PyBytes_Type, your_iterable, NULL);

Любая итерация, которая возвращает значения от 0 до 255, должна работать. Вы можете выбрать PyObject_Call*, который вам проще всего использовать.

Я подозреваю, что написание итерируемого на C / C ++ будет более трудным, чем написание l oop.

...