Как получить чужой необработанный указатель байтов из схемы bytevector? - PullRequest
1 голос
/ 19 апреля 2020
Схема

обеспечивает тип bytevector, который можно использовать для выполнения операций низкого уровня над байтами и массивом байтов (см. Руководство r6rs и chez ). Тем не менее, он, похоже, не обеспечивает способ извлечения базового указателя на массив байтов, который он хранит, и мне нужен этот указатель для передачи в сторонние C функции для заполнения или чтения данных из байтового вектора ,

Чтобы быть более точным относительно контекста, я пытаюсь написать некоторый код для низкоуровневой обработки байтов в Idris2, который использует Scheme в качестве бэкэнда, но я новичок ie в Scheme, поэтому я Я, конечно, упускаю из виду нечто очевидное: какой предпочтительный подход для извлечения этого указателя из байтового вектора?

1 Ответ

3 голосов
/ 19 апреля 2020

Операция, которая возвращает адрес байтовектора в виде целого числа, опасно опасна, поскольку сборщик мусора может впоследствии переместить байтовый вектор и поместить туда другие объекты. Передача устаревшего адреса в код C может привести к повреждению памяти.

Документы для foreign-procedure схемы Chez говорят, что аргумент, объявленный как u8*, принимает байтовый вектор и передает адрес его содержания для внешней функции. Это безопасно, потому что FFI и G C взаимодействуют, чтобы гарантировать, что объект не перемещается между взятием адреса и вызовом сторонней функции --- но смотрите предупреждение о сохранении указателя во внешних структурах данных. См. Также lock-object, который временно препятствует перемещению или возвращению объекта G C.

В Racket иностранные типы _bytes и _pointer работают аналогично. Также есть операция ptr-add, которая комбинирует объект, подобный указателю, со смещением. Например, если bs является строкой байтов, то (ptr-add bs 1 _byte) надежно преобразуется в адрес второго байта bs, даже если G C перемещается bs. Я не знаю, есть ли у Chez похожая функция.

...