[racket] Freeing FFI resources
Eric Dobson wrote:
> I am dealing with a foreign library that has functions that return
> error messages in a char** input argument. These need to be explicitly
> freed by calling another function. I figured out how to get them into
> racket strings by using the _ptr and the _string ctype. But I didn't
> see a way to capture the value before conversion to a racket string so
> that I could free the original string, and continue to use the _string
> conversion process. Is there an easy way to do these two thing
> together?
You can pass a bytes object to foreign code that expects a char*, and
it'll be passed as a pointer to the byte data. So use _bytes instead of
_string, call (probably) bytes->string/utf-8, and then pass the bytes
object to the foreign function that frees them.
I'd be wary of the bytes/free example: I'd free the bytes ASAP instead
of using a finalizer. I confused the crap out of Racket's GC by keeping
externally-managed memory around that was pointed at by Racket-owned
objects with registered finalizers. (I made sure the external memory was
properly atomic, like bytes are.)
While running a simple loop that allocated these mixed-memory objects
and immediately stopped referencing them, Racket's memory usage would
vary about 200MB. After I changed to immediate frees and Racket-owned
memory only, memory usage was constant, as I expected.
I don't know if the problem was caused by having too many finalizers
registered, if it was because Racket's GC thought Racket was using much
less memory than it actually was, or a combination of the two.
Neil T