Memory management for C bindings

When writing bindings for a C library which performs memory allocations, how can we perform automatic memory management in the style of Julia with the external free functions? We want something similar to the defer keyword, like the following:

my_ptr = @ccall mylib.myAlloc(alloc_bytes)::Ptr{UInt8}
defer @ccall mylib.myFree(my_ptr)

Ideally we would like to plug into the garbage collector to make this kind of C call memory safe.

The usual approach is to wrap the output of your ccall in a Julia mutable struct that hides the raw pointer, and has a finalizer that calls the C destructor.

For example, ZMQ.jl does this to wrap the raw void* returned by zmq_socket in the C library with a Julia Socket type with a finalizer that calls zmq_close on the pointer.

In general, you rarely want to expose a raw C pointer-based API to the user; always wrap it.

6 Likes