mit-scheme-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[MIT-Scheme-devel] struct return values in the FFI


From: craven
Subject: [MIT-Scheme-devel] struct return values in the FFI
Date: Thu, 03 Sep 2015 12:56:50 +0200
User-agent: Notmuch/0.20.1 (http://notmuchmail.org) Emacs/24.5.1 (x86_64-unknown-linux-gnu)

Greetings!

I've again been playing around with the FFI, and found that struct
parameters seem to work beautifully, however struct return values suffer
from the following problem.

Given the following cdecl:

 (typedef TCOD_color_t (struct (r uchar) (g uchar) (b uchar)))

 (extern TCOD_color_t
         TCOD_color_RGB
         (r uchar)
         (g uchar)
         (b uchar))
                      
I'd expect to have the following call work:

 (define c (malloc (C-sizeof "TCOD_color_t") 'TCOD_color_t))
 (C-call "TCOD_color_RGB" c 1 2 3)

However, I get the following error in the repl:

 ; Evaluation aborted on The object #[alien 17 |TCOD_color_t| 
0x00000000006a1de0], passed as the second argument to c-call, is not the 
correct type..

Inspecting the shim, I see the following code generated for
Scm_TODO_color_RGB:

 check_number_of_args (4);
 r = arg_ulong (2);
 g = arg_ulong (3);
 b = arg_ulong (4);

This seems to be incorrect, as the number of arguments should be 5 (one
for the procedure, one for the struct return value, three for the actual
parameters).

If I manually adjust as follows:

 check_number_of_args (5);
 r = arg_ulong (3);
 g = arg_ulong (4);
 b = arg_ulong (5);

and recompile, things seem to work fine.

As far as I understand, the code that generates these lines is in
src/ffi/generator.scm:224.

It has

 (let* ((alien-ret-arg? (ctype/pointer? (definite-ctype ret-ctype includes))
        (nargs
         (number->string (+ (length params) (if alien-ret-arg? 2 1))))))
  ....)

It seems, that alien-ret-arg? should be true also for struct (and union)
types. Something along the lines of

 (or (ctype/pointer? ...)
     (ctype/struct? ...)
     (ctype/union? ...))

I've tried to build this, however for some reason I cannot build the
current git head at all :-/

 (cd microcode && make all)
 make[1]: Entering directory '/home/nex/mit-scheme/src/microcode'
 make[1]: Nothing to be done for 'all'.
 make[1]: Leaving directory '/home/nex/mit-scheme/src/microcode'
 (echo '(with-working-directory-pathname "runtime"' && \
  echo '  (lambda ()' && \
 echo '    (cref/generate-trivial-constructor "runtime")))') \
| 'mit-scheme-x86-64' --batch-mode --band ./tools/syntaxer.com
;Loading "/home/nex/.scheme.init"... aborted
(echo '(with-working-directory-pathname "runtime"' && \
 echo '  (lambda () (load "runtime.sf")))') \
| 'mit-scheme-x86-64' --batch-mode --band ./tools/syntaxer.com
;Loading "/home/nex/.scheme.init"... aborted
;The object #t, passed as an argument to fluid, is not a fluid.
;To continue, call RESTART with an option number:
; (RESTART 1) => Return to read-eval-print level 1.

2 error>
End of input stream reached.Makefile:384: recipe for target 'syntax-runtime' 
failed
make: *** [syntax-runtime] Error 1

Would anyone more knowledgable than me chime in on whether this would be
a possible fix? There are very few C APIs that *don't* use direct struct
arguments or return values somewhere, it would be great if this were
supported (as it almost is anyway).

Thanks for any help,

Peter



reply via email to

[Prev in Thread] Current Thread [Next in Thread]