Главная » Haskell » Модуль Storable интерфейс для маршализации

0

В модуле Storable описан важнейший интерфейс для маршализации — класс Storable. Этот класс предоставляет интерфейсные функции для осуществления примитивного маршалинга типов данных, а потому является непосредственной частью системы FFI языка Haskell. Предполагается, что этот модуль подключается в проект при помощи реимпорта из модуля Foreign, однако если имеется необходимость использования этого модуля отдельно, его можно подключить следующим образом:

import  Foreign.storable

В модуле описан единственный класс, ничего более.

Класс: Storable

Описание: методы этого класса облегчают запись значений примитивных типов в последовательную память (которая может быть выделена при помощи функций, описанных ранее в этой главе), а также чтение значений из последовательной памяти.  Кроме  того, этот класс включает в себя методы для вычисления необходимого количества  памяти, а также  для получения  ограничений на выравнивание значений.

Определение:

class Storable a  where sizeOf           ::  a ->  Int alignment     ::  a  ->  Int

peekElemOff :: Ptr   a ->  Int ->  IO  a pokeElemOff :: Ptr   a ->  Int ->  a  ->  IO () peekByteOff  :: Ptr   b  ->  Int ->  IO a pokeByteOff  :: Ptr  b ->  Int ->  a ->  IO () peek               ::  Ptr   a ->  IO a

poke              :: Ptr   a ->  a ->  IO ()

Адреса памяти представлены в виде указателей типа Ptr  (см. стр. 462) на типы данных, являющиеся экземплярами рассматриваемого класса. Такие указатели помогают обеспечить определённый уровень безопасности при работе с FFI (невозможно использовать указатель на один тип в качестве указателя на другой тип без явного преобразования типов). Кроме того, такие указатели помогают системе типизации языка Haskell применять определённые методы маршализации для заданных типов данных.

Все процессы маршализации между языком Haskell и прочими  сторонними языками программирования заключаются в преобразовании алгебраических типов данных языка Haskell в неструктурированные последовательности байт, и наоборот. Для кодирования таких процессов маршализации необходимо манипулировать двоичным представлением  значений в последовательной памяти. Класс Storable как раз и предлагает интерфейс для подобной манипуляции.

Метод sizeOf  возвращает количество  байт, необходимое для  хранения значения заданного типа. Значение аргумента не используется в вычислениях, поэтому в качестве значения можно (и обычно это делается) передавать значение undefined  соответствующего типа. Также и метод alignment возвращает количество байт, необходимых для выравнивания значений в памяти.

Пара методов peekElemOff и pokeElemOff используются для чтения и записи элементов массива в последовательной памяти. Первый аргумент задаёт указатель на начало массива, второй — смещение  в элементах массива (не в байтах). Третий аргумент метода pokeElemOff, соответственно, задаёт значение, которое необходимо записать. Результат этих методов возвращается в монаде IO.

Абсолютно так же работает пара методов peekByteOff  и pokeByteOff,  которые вторым аргументом принимают смещение от  начала адреса в байтах. Результат этих методов также возвращается в монаде IO.

Наконец, методы peek и  poke используются для чтения и  записи значения по определённому адресу в памяти. Предыдущие  две пары методов могут быть выражены через эти примитивные функции. Обычно в экземплярах класса Storable определяют только методы peek и poke.

Осталось отметить, что экземплярами класса Storable определаны все примитивные типы языка Haskell, все внешние  типы, описанные в модуле Types (см. подраздел 10.1.3.), а также все целочисленные типы для представления знаковых и беззнаковых величин различной точности. Также в качестве экземпляров  определены указатели на функции (FunPtr),  простые (Ptr) и  стабильные (StablePtr) указатели. Само собой разумеется,  что типы, параметризуемые такими указателями, сами должны быть экземплярами класса Storable.

Источник: Душкин Р. В., Справочник по языку Haskell. М.: ДМК Пресс, 2008. 544 с., ил.

По теме:

  • Комментарии