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 mailing list MIT-Scheme-devel@gnu.org https://lists.gnu.org/mailman/listinfo/mit-scheme-devel