Как я могу выделить и повторно использовать структуру C из Haskell?

В частности, я пытаюсь изучить интерфейс сторонних функций Haskell, написав привязку к библиотеке игр Allegro. В родном языке C Allegro цикл основного события выглядит примерно так:

// initialize event struct
ALLEGRO_EVENT event;

// main loop
while (running) {
    if (al_get_next_event(event_queue, &event)) {
        // process event here ...
    }
}

Используя ghc и hsc2hs, я могу написать вызов сторонней функции, такой как:

foreign import ccall "allegro5/allegro.h al_get_next_event"
    alGetNextEvent :: EventQueue -> Ptr (Event) -> IO (CInt)

где EventQueue указатель на непрозрачную структуру и Event это Storable экземпляр основан на C ALLEGRO_EVENT,

В идеале для функции Haskell, ориентированной на пользователя, я хотел бы иметь сигнатуру типа

getNextEvent :: EventQueue -> Maybe Event

который отвлечет инициализацию ALLEGRO_EVENT struct и логическое возвращаемое значение.

У меня вопрос, как мне написать эту функцию, чтобы максимизировать эффективность памяти? Я мог бы malloc новый указатель на Event внутри метода и используйте его, но так как я работаю с данными на основе C, я хочу убедиться, что я повторно использую существующее пространство и не выделяю постоянно новые структуры. Я также хочу избежать использования пользователем malloc структуры и передавать ее при каждом вызове.

Любой совет?

1 ответ

Решение

Как правило, если это данные локальной области, вы должны использовать

Если данные имеют большую область,

Это хороший выбор, так как он очень быстрый, вы можете подключить финализаторы, и вам не нужно убирать самостоятельно.

Среда выполнения GHC позаботится о максимальном повторном использовании пространства для вас, поэтому вам не нужно слишком беспокоиться об эффективности, например, закрепив изменяемый буфер памяти на месте. Просто позвольте GC позаботиться о вещах.

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