alien.inline
is nice, but it would be even nicer to have factor values automatically
marshalled to and from their C equivalents. alien.marshall
enables this.
A short example:
USING: alien.inline.syntax alien.marshall.syntax ;
IN: marshall-test
C-LIBRARY: short-example
CM-STRUCTURE: rectangle
{ "int" "width" }
{ "int" "height" } ;
CM-FUNCTION: int area ( rectangle c )
return c.width * c.height;
;
CM-FUNCTION: void incr ( int* a, int delta )
*a += delta;
;
;C-LIBRARY
and output:
( scratchpad ) <rectangle> 3 >>width 5 >>height
--- Data stack:
T{ rectangle f ALIEN: 36777744 f }
( scratchpad ) area
--- Data stack:
15
( scratchpad ) 3 incr
--- Data stack:
18
As you can see, struct fields are marshalled, as are struct arguments. Output parameters are unmarshalled and pushed on the stack after the return value (if not void).
Non–false c-ptrs are not marshalled, they are passed to the C
function unchanged. It is assumed that if you pass a c-ptr you
know what you are doing and can clean up after yourself.
Return values and output parameters which are pointers, are assumed to be pointers to a single value. Factor words which call C functions returning pointers to arrays (single or multi–dimensional) will need to include hand–coded unmarshalling.
Return pointers and output pointers are freed after unmarshalling. Struct
fields are an exception to this: fields containing pointers will need to be
explicitly freed once the struct is no longer needed (overriding the struct’s
dispose* method is a good way to do this).
alien.marshallwords follow the same pattern as
alien.inline, but with a CM- prefix instead of
C-.
There are also M- prefixed words. These do not generate C code.
They behave like their counterparts in alien.syntax with the
addition of marshalling and unmarshalling of values.
Next up: alien.c++-templates…
A new feature has been added to Factor that might be helpful in your work: http://docs.factorcode.org/content/article-classes.struct.html
ReplyDeleteHaven't heard much from your blog lately!