Hi,
I've been playing around with Gambit's foreign function interface today, and the big stumbling block i've hit is that I cannot easily pass u8vectors to native code, i.e. u8vector is not compatible with (pointer void) or (pointer unsigned-int8).
Is there a chance this might be changed in the future?
I would _not_ want the address of a copy of the bytevector's contents to be passed to c-code but a pointer to the original u8vector's storage location instead.
I am guaranteed that GC will not move my memory for the duration of this foreign call, am I not? (unless of course, scheme is reentered from within that native call, in which case all bets are off, right?)
If there's an easier way of accomplishing this already supported I would of course love to hear it.
Best regards,
Andreas
Afficher les réponses par date
Andreas Huber wrote:
Hi,
I've been playing around with Gambit's foreign function interface today, and the big stumbling block i've hit is that I cannot easily pass u8vectors to native code, i.e. u8vector is not compatible with (pointer void) or (pointer unsigned-int8).
Is there a chance this might be changed in the future?
I would _not_ want the address of a copy of the bytevector's contents to be passed to c-code but a pointer to the original u8vector's storage location instead.
Pass the scheme-object as is. You can then either use the accessor macros from gambit.h, or cast it's body address to the pointer type you like.
(define (frobvec vec) (if (not ((c-lambda (scheme-object) scheme-object " if (___U8VECTORP(___arg1) && ___INT(___U8VECTORLENGTH(___arg1))>=XYZ) { char *p= ___CAST(char*,___BODY(___arg1)); frobvec(p); ___result=___TRU; } else { ___result=___FAL; } ") vec)) (error "invalid type of:" vec)))
(Note: I've typed this right into the mail without testing.)
You could also use c-define-type with your own conversion macros to abstract the check and cast away.
I am guaranteed that GC will not move my memory for the duration of this foreign call, am I not? (unless of course, scheme is reentered from within that native call, in which case all bets are off, right?)
Allocating scheme objects from C code can also trigger the GC.
Note that bigger u8vector's are allocated as still objects and then will never move. You can check if a memory-allocated object (check with ___MEM_ALLOCATED(obj) if you don't know if it's memory-allocated) is a still object with the code (___HD_TYP(___HEADER(obj))==___STILL).
Christian.
PS. if you're after the greatest possible speed, you can also use the undocumented (and unofficial) ##c-code syntax (which does not offer *any* type conversions by itself, but as reward also doesn't consume any cpu cycles):
(define (frobvec2 vec) (if (not (##c-code " if (___U8VECTORP(___ARG1) && ___INT(___U8VECTORLENGTH(___ARG1))>=10) { char *p= ___CAST(char*,___BODY(___ARG1)); frobvec(p); ___RESULT=___TRU; } else { ___RESULT=___FAL; } " vec)) (error "invalid type of:" vec)))
Christian.