[racket] FFI: problems using (_list i _string)

From: keydana at gmx.de (keydana at gmx.de)
Date: Tue Jun 7 08:41:44 EDT 2011

Hi Thomas again,

for time reasons, I'm answering the second (or rather, first) part of your mail separately :-;

Just wanted to say that your code suggestion
>  (define (string-list->fixed-width-array width items)
>    (string-join (map (cut string-pad-right <> width #\null) items)))

was even more helpful than I was aware of at first (it being always good to have code examples) :-)
I tried writing a simple null-appending and string-joining function first, but it turned out that padding every string to an equal length is a necessity, simply null-terminating them is not enough :-;

So thanks again,

>  (provide
>   (all-defined-out))
>> [...]
>> Regarding racket garbage collection, on the one hand, and c pointer
>> freeing, that is generally a topic I'm very unsure about and could
>> perhaps use some "basic" advice (more basic  than the FFI reference,
>> I mean).  For example, do I have to explicitly "destroy"  c pointers
>> somehow, and if so, when? In the case of my c library given, I
>> assume I have to implement every function like '<object>Free' and
>> call it when I'm done, but apart from that?
>> [...]
> Ok, I'll try to sum up a few basics: First it's important to note that
> values allocated by Racket and blocks allocated by C code live in
> different memory areas and are handled differently. While Racket
> values are reclaimed automatically by the garbage collector some time
> after they are no longer referenced, blocks allocated from C live
> forever unless explicitly destroyed. These two worlds know nothing
> about each other by default.
> The pointers your code handles never have to be destroyed explicitly,
> but the objects they point to may have to be destroyed. There is no
> simple general rule when and how this has to happen. It all depends on
> the way the C code is designed and what mechanisms it uses for memory
> management.
> In the most simple situation, you do not use any C functions that
> allocate and store or return (pointers to) blocks of memory, so you
> can just let all the data live in the memory area managed by Racket
> and let the garbage collector do its job without caring about manually
> freeing any blocks of memory. C structures can be allocated through
> Racket's garbage collector, too, and they will be reclaimed just like
> Racket values some time after all pointers referring to them go out of
> scope. Look at the documentation of malloc in the ffi/unsafe module
> for details about memory allocation from the Racket side.
> Another case encountered frequently is that there are C functions
> creating, operating on and destroying pointers to some opaque data
> structure. These structures do not live in Racket's managed memory, so
> calls to the creation functions have to be matched by calls to the
> destruction functions or the objects will stay in memory until the
> process terminates.
> In this situation you have two basic choices: You can either provide
> bindings to the functions that create and destroy objects and require
> any client code to handle memory management of those objects
> explicitly, manually destroying them when they are no longer
> needed. Or you can set up an automatism in Racket that ensures all
> those objects created by calls from Racket are freed some time after
> Racket code no longer holds any references to them. An easy way to
> achieve this is by decorating the bindings for the creation and
> destruction procedures using allocator and deallocator from the
> ffi/unsafe/alloc module. However, care has to be taken that no code
> outside Racket is still using the objects when they are reclaimed by
> the Racket garbage collector. Some C libraries use reference counting
> to better handle the situation that different pieces of code may hold
> references to an object for random periods of time; the
> ffi/unsafe/alloc module also has support for that situation.
> Things get progressively more complicated if the C structures put
> inside Racket's memory areas contain pointers themselves, if
> structures outside Racket's memory areas contain pointers to Racket
> values, or if callbacks from C into Racket are used.
>> [...]
>> I hope I didn't ask too many too basic questions now, but never
>> having done any c programming and just knowing the concepts
>> "theoretically", there a quite some things about using FFI I don't
>> automatically understand from the Reference...
>> [...]
> Among all the FFIs I have used, Racket's is one of the most
> comfortable and full featured ones. However, its features imply
> complexity, too, and I can well imagine that without any prior
> experience in low level programming and manual memory management, one
> can easily get lost. So questions have to be expected :-)
> Ciao,
> Thomas
> -- 
> When C++ is your hammer, every problem looks like your thumb.

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.racket-lang.org/users/archive/attachments/20110607/eb017380/attachment.html>

Posted on the users mailing list.