Question

In particular, I'm trying to learn Haskell's foreign function interface by writing a binding to the Allegro game library. In Allegro's native C, the main event loop looks something like this:

// initialize event struct
ALLEGRO_EVENT event;

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

Using ghc and hsc2hs, I can write a foreign function call like:

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

where EventQueue is a pointer to an opaque structure and Event is a Storable instance based off of C's ALLEGRO_EVENT.

Ideally, for the user-facing Haskell function, I would like to have a type signature like

getNextEvent :: EventQueue -> Maybe Event

which would abstract away initializing the ALLEGRO_EVENT struct and boolean return value.

My question is, how should I write this function to maximize memory efficiency? I could malloc a new pointer to Event inside the method and use that, but since I'm working with C-based data, I want to make sure I'm re-using existing space and not constantly allocating new structs. I also want to avoid having the user malloc the struct and pass it in to every call.

Any advice?

Was it helpful?

Solution

Typically, if it is locally scoped data, you would use

If the data has longer scope,

is a good choice, since it is very fast, you can attach finalizers, and you don't have to clean up on your own.

The GHC runtime takes care of maximally reusing space for you, so there's not too much of a need to worry about efficiency by e.g. pinning a mutable memory buffer in place. Just let the GC take care of things.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top