[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
- [MIT-Scheme-devel] struct return values in the FFI,
craven <=