Friday, July 17, 2009

alien.marshall: marshalling between factor and C

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;


and output:

( scratchpad ) <rectangle> 3 >>width 5 >>height

--- Data stack:
T{ rectangle f ALIEN: 36777744 f }
( scratchpad ) area

--- Data stack:
( scratchpad ) 3 incr

--- Data stack:

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

1 comment:

  1. A new feature has been added to Factor that might be helpful in your work:

    Haven't heard much from your blog lately!