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

From: keydana at gmx.de (keydana at gmx.de)
Date: Sun Jun 5 13:02:26 EDT 2011

Hi Thomas,

thanks a lot for your answer!

> if dtext is actually an alias for char, as you write, then the
> signature of the C function implies that it expects a string, not a
> list of strings, as its third argument.

Oh, you are right, of course! I was mislead by the integer case, where indeed an array was expected...
In some example c code available, the argument actually is a two-dimensional array of chars, which then of course is passed as a pointer to char, and I guess the separation of strings is achieved by the null-termination of c strings then...
I wonder how I am going to do this in racket, should I append null to every string, string-append the strings and then pass a single string to the function? I suppose there is a better way?

> The second problem with the binding definition is that it doesn't
> convey any information about the length of the list to the C function,
> which is almost certain to cause trouble. Judging by your description
> of the C function's contract, simply adding a #f to the end of the
> list before passing it to the marshaller should do the job here: Just
> replace (data : ...) by (data : ... = (append data '(#f))).

I see... now that I'm not going to use _list (in this case) any more, it will not be applicable, but it's good to know!

> Finally, when passing ephemeral data like this array and the string
> pointers it contains to C, one has to be careful that the Racket
> garbage collector doesn't interfer with assumptions made on the C side
> about the incoming data: If the function doesn't copy the data but
> simply stores the pointers somewhere and returns, the data may be
> garbage collected before it is used again in some other C function,
> which of course will fail miserably in that case.

Thanks for pointing this 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?
(Sorry for asking such a plain question.)
In this concrete case, what would one do  - use a non-automatically-freed pointer and explicitly free it afterwards?

> I think that in the lexical scope where the expansion of the _list
> syntax inside the _fun syntax places the output argument length
> computation, the name of the output argument is bound to the raw
> pointer from C. You can circumvent this by using a different name for
> the argument of the Racket wrapper procedure and the argument of the C
> function — check the description of the _fun syntax for the maybe-args
> part.

I will have a look, thanks!

Thank you again, 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...


> Ciao,
> Thomas
> -- 
> When C++ is your hammer, every problem looks like your thumb.

Posted on the users mailing list.