特别是,我试图通过编写与Allegro游戏库的绑定来学习Haskell的外部函数接口。在Allegro的本地C语言中,主事件循环如下所示:

// 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是基于C的StorableALLEGRO_EVENT实例。

理想情况下,对于面向用户的Haskell函数,我希望有一个类型签名,例如

getNextEvent :: EventQueue -> Maybe Event


这将抽象化初始化ALLEGRO_EVENT结构和布尔值返回值。

我的问题是,我应该如何编写此函数以最大化内存效率?我可以在方法内部分配一个指向Event的新指针,并使用它,但是由于我使用的是基于C的数据,因此我想确保自己正在重新使用现有空间,而不是不断分配新结构。我还想避免让用户malloc结构并将其传递给每个调用。

有什么建议吗?

最佳答案

通常,如果是本地范围的数据,则应使用


alloca


如果数据的范围更长,


mallocForeignPtr


是个不错的选择,因为它非常快,您可以附加终结器,而不必自己清理。

GHC运行时会为您最大程度地重用空间,因此无需过多担心效率问题,例如,将可变的内存缓冲区固定到位。只需让GC来处理。

关于c - 如何从Haskell分配和重用C结构?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/10955202/

10-12 18:12
查看更多