How to pass a u8vector to the FFI
You do this, by declaring the passed u8vector as a scheme-object in the c-lambda definition. The memory pointer to the u8vector's contents in the C code is resolved by void *u8vectorptr = ___CAST(void*,&___FETCH_U8(___BODY(theu8vectorschemeobjectvariable),___INT(0))); Remember that the pointer is only to be kept until the next return to Scheme. Mikael 2010/3/30 Álvaro Castro-Castilla <alvaro.castro.castilla@gmail.com>
Hi!
Is there a way to pass a u8-vector to a FFI interface somehow? The way I expect this to work is through a (pointer unsigned-char), but it obviously doesn't work, claiming a proper C pointer. I would like to be able to build this arrays from Scheme code. Is there a way?
Currently I have to call a FFI function to set char by char, calling the c-lambda function too many times.
One thing that could work is something that converts u8-vectors to unsigned char* arrays, does that exist in Gambit?
Thanks,
Álvaro
_______________________________________________ Gambit-list mailing list Gambit-list@iro.umontreal.ca https://webmail.iro.umontreal.ca/mailman/listinfo/gambit-list
Afficher les réponses par date
El 30 de marzo de 2010 14:39, Mikael <mikael.trash@gmail.com> escribió:
You do this, by declaring the passed u8vector as a scheme-object in the c-lambda definition.
The memory pointer to the u8vector's contents in the C code is resolved by
void *u8vectorptr = ___CAST(void*,&___FETCH_U8(___BODY(theu8vectorschemeobjectvariable),___INT(0)));
Remember that the pointer is only to be kept until the next return to Scheme.
Mikael
Thanks!! :) May I ask where did you get this from? Gambit's source code? I can't find docs about this... Álvaro
2010/3/30 Álvaro Castro-Castilla <alvaro.castro.castilla@gmail.com>
Hi!
Is there a way to pass a u8-vector to a FFI interface somehow? The way I expect this to work is through a (pointer unsigned-char), but it obviously doesn't work, claiming a proper C pointer. I would like to be able to build this arrays from Scheme code. Is there a way?
Currently I have to call a FFI function to set char by char, calling the c-lambda function too many times.
One thing that could work is something that converts u8-vectors to unsigned char* arrays, does that exist in Gambit?
Thanks,
Álvaro
_______________________________________________ Gambit-list mailing list Gambit-list@iro.umontreal.ca https://webmail.iro.umontreal.ca/mailman/listinfo/gambit-list
Hallo, 2010/3/30 Mikael <mikael.trash@gmail.com>:
You do this, by declaring the passed u8vector as a scheme-object in the c-lambda definition. The memory pointer to the u8vector's contents in the C code is resolved by void *u8vectorptr = ___CAST(void*,&___FETCH_U8(___BODY(theu8vectorschemeobjectvariable),___INT(0))); Remember that the pointer is only to be kept until the next return to Scheme.
AFAIK you do not need the last ___INT(). Cheers, -- -alex @asandroq http://www.ventonegro.org/
2010/3/30 Alex Queiroz <asandroq@gmail.com>
Hallo,
2010/3/30 Mikael <mikael.trash@gmail.com>:
You do this, by declaring the passed u8vector as a scheme-object in the c-lambda definition. The memory pointer to the u8vector's contents in the C code is resolved by void *u8vectorptr =
___CAST(void*,&___FETCH_U8(___BODY(theu8vectorschemeobjectvariable),___INT(0)));
Remember that the pointer is only to be kept until the next return to Scheme.
AFAIK you do not need the last ___INT().
Cheers, -- -alex @asandroq http://www.ventonegro.org/
It seems that ___FECTH__U8 needs two arguments, what do you mean by not needed then? With ___INT(0) it works fine, but is interesting if there is a shorter way to express the same also. Thanks :) Álvaro Castro-Castilla
Hallo, 2010/3/30 Álvaro Castro-Castilla <alvaro.castro.castilla@gmail.com>:
It seems that ___FECTH__U8 needs two arguments, what do you mean by not needed then? With ___INT(0) it works fine, but is interesting if there is a shorter way to express the same also.
I always use ___FETCH_U* with a C integer as the second argument, i. e., I don't use the ___INT() conversion macro. Cheers, -- -alex @asandroq http://www.ventonegro.org/
On 2010-03-30, at 10:34 AM, Alex Queiroz wrote:
I always use ___FETCH_U* with a C integer as the second argument, i. e., I don't use the ___INT() conversion macro.
Indeed the ___INT(x) macro converts the fixnum x into a C int. It is the inverse of the ___FIX(n) macro which converts a C int into a fixnum. The simplest way to do what you want is: char *u8vectorptr = ___CAST(char*,___BODY(theu8vectorschemeobjectvariable)); then u8vectorptr[i] = ...; Note that you can only do this if the u8vector will not move (it is either a ___STILL or ___PERM object, or you don't make any calls back to Scheme or the Gambit memory allocator inside your C function. Marc
Dear Marc, Can a present object (u8vector etc.) be switched between ___STILL / ___MOVABLE / ___PERMANENT, if so how from Scheme respectively C? Also just to check, on vector create-time there's no way to specify GC object type right (in make-u8vector etc.)? Many thanks, Mikael 2010/3/30 Marc Feeley <feeley@iro.umontreal.ca>
On 2010-03-30, at 10:34 AM, Alex Queiroz wrote:
I always use ___FETCH_U* with a C integer as the second argument, i. e., I don't use the ___INT() conversion macro.
Indeed the ___INT(x) macro converts the fixnum x into a C int. It is the inverse of the ___FIX(n) macro which converts a C int into a fixnum.
The simplest way to do what you want is:
char *u8vectorptr = ___CAST(char*,___BODY(theu8vectorschemeobjectvariable));
then
u8vectorptr[i] = ...;
Note that you can only do this if the u8vector will not move (it is either a ___STILL or ___PERM object, or you don't make any calls back to Scheme or the Gambit memory allocator inside your C function.
Marc
_______________________________________________ Gambit-list mailing list Gambit-list@iro.umontreal.ca https://webmail.iro.umontreal.ca/mailman/listinfo/gambit-list
I believe you can use something like ___CAST(___sU8VECTOR*,___BODY_AS(obj,___tSUBTYPED)) Look for examples in gambit.h Brad
On 2010-03-30, at 10:39 AM, Bradley Lucier wrote:
I believe you can use something like
___CAST(___sU8VECTOR*,___BODY_AS(obj,___tSUBTYPED))
The first argument to ___CAST must be a type... but ___sU8VECTOR is the subtype tag (an integer constant). So you want: ___CAST(___U8*,___BODY_AS(obj,___tSUBTYPED)) because ___U8 is defined as an unsigned char (on most platforms) by gambit.h . Marc
2010/3/30 Marc Feeley <feeley@iro.umontreal.ca>
On 2010-03-30, at 10:39 AM, Bradley Lucier wrote:
I believe you can use something like
___CAST(___sU8VECTOR*,___BODY_AS(obj,___tSUBTYPED))
The first argument to ___CAST must be a type... but ___sU8VECTOR is the subtype tag (an integer constant). So you want:
___CAST(___U8*,___BODY_AS(obj,___tSUBTYPED))
because ___U8 is defined as an unsigned char (on most platforms) by gambit.h .
Marc
Yes. I've tried all methods and they all work. Assuming that the third argument is the u8vector: void *u8vectorptr = ___CAST(void*,&___FETCH_U8(___BODY(___arg3),___INT(0))); void *u8vectorptr = ___CAST(void*,&___FETCH_U8(___arg3,0)); void *u8vectorptr = ___CAST(___U8*,___BODY_AS(___arg3,___tSUBTYPED)); void *u8vectorptr = ___CAST(void*,___BODY(___arg3)); They all can be cast to uchar* directly: unsigned char *u8vectorptr = ___CAST(___U8*,___BODY_AS(___arg3,___tSUBTYPED)); All produce the result I expect (apparently). Thanks a lot for all your explanations. I'd like to put this in the wiki page: http://dynamo.iro.umontreal.ca/~gambit/wiki/index.php/Using_Gambit_with_Exte... is that ok?
_______________________________________________ Gambit-list mailing list Gambit-list@iro.umontreal.ca https://webmail.iro.umontreal.ca/mailman/listinfo/gambit-list
On 2010-03-30, at 10:52 AM, Álvaro Castro-Castilla wrote:
Thanks a lot for all your explanations. I'd like to put this in the wiki page:
http://dynamo.iro.umontreal.ca/~gambit/wiki/index.php/Using_Gambit_with_Exte...
is that ok?
Sure. Don't forget the caveat about movable objects (i.e. the C compiler does not know that the GC might move objects, so the C code must be written to avoid calling the GC either directly or indirectly). Marc
participants (6)
-
Alex Queiroz -
Bradley Lucier -
Marc Feeley -
Mikael -
Mikael -
Álvaro Castro-Castilla