[Ecls-list] arrays as parameters to c-inlined code

Goffioul Michael goffioul at imec.be
Tue Sep 11 07:58:19 UTC 2007


> Greetings,
> 
> I'm trying to pass an array reference to c-inlined code, 
> without much success.  Well, I can get it into the c-inlined 
> code, I just can't seem to do anything with it when it comes 
> out.  I have the feeling that there's something fundamental 
> that I don't understand, so I'd be grateful for any 
> pointers...  I'm really not sure where to go from here.
> 
> I've tried using the approaches below, but both fail when any 
> attempt is made to access the array once the C-code 
> completes.  In both cases the C-code seems to execute 
> correctly, but then breaks as follows:
> 
>   > (load "test.fas")
>    ;;; Loading "c:/_/pvt/tmp/test.fas"
>    "c:/_/pvt/tmp/test.fas"
>    > (load-native-constants-0)
>    [0] : 2
>    [1] : 4
>    [2] : 8
>    Broken at EVAL.No restarts available.
>    Broken at LOAD-NATIVE-CONSTANTS-0.
>    >> (quit)
>    3435462 is not of type SI:FOREIGN-DATA.
> 
> In the error above, the final error message shows after the 
> (quit) because of the way rxvt captures the output.  I've 
> produced this output on Windows under MinGW, but I see the 
> same problems on Linux.
> 
> The code that I've tried is:
> 
> [1] using with-foreign-object
> 
>    (defun load-native-constants-0 ()
> 
>      (ffi:with-foreign-object
>        (consts '(:array :unsigned-byte 3))
> 
>        (ffi:clines "#include <sys/types.h>")
>        (ffi:c-inline
>          (consts) (:unsigned-byte*)
>          :void    ; no return value
>          "{
>             uint8_t* consts = #0;
>             consts[0] = 2;
>             printf(\"[0] : %d\\n\", consts[0]);
>             consts[1] = 4;
>             printf(\"[1] : %d\\n\", consts[1]);
>             consts[2] = 8;
>             printf(\"[2] : %d\\n\", consts[2]);
>          }")))

This is due to the fact that #0 is not mapped to a 
uint8_t* object, but simply to the internal cl_object
object (see object.h). By casting it to uint8_t* and
modifying it, you corrupt the object and it is not
recognized anymore by ECL. What you probably want is

uint8_t* consts = #0->foreign.data;

When you have such problems, the easiest is to look
at the generated C code (use ":c-file t" argument to
compile-file).

Michael.




More information about the ecl-devel mailing list