Как вернуть список или массив из блока 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,

Другие вопросы по тегам