Как вернуть список или массив из блока C в inline-c на Haskell?
Как я могу получить список или массив из блока C в inline-c на Haskell? Другими словами, как построить сложные данные в C и работать с ними в Haskell. Что-то вроде этого:
foo :: IO [Int]
foo = do
what? <- [C.block| <what?> {
ints = calloc(10, sizeof(int));
// ...
return <what?>;
} |]
return <what?>
Я мог бы обернуть указатель и размер в некоторый тип Haskell, но я хотел бы работать со списком в Haskell, распечатывать его, кодировать в JSON и т. Д.
1 ответ
Решение
Вернуть указатель на массив из вашего кода C и использовать peekArray
составить список.
import Foreign.Marshal.Array
import Language.C.Inline
foo :: Int -> IO [Int]
foo size = [exp| int* { calloc($(int size), sizeof(int)) }] >>= peekArray size
peekArray
принимает аргумент указателя и количество элементов для чтения. Итеративно увеличивает указатель size
раз, вытягивая элементы из массива, используя тип Storable
экземпляр (в этом случае, Int
).
Может быть эффективнее превратить ваш массив в распакованный Vector
,