Hi!
This is a different question from my previous silly question.
All though it's really cool that I can take a C function with signature: void foo(int *); and in scheme land create a (scheme-foo) so that I can do:
(define bar (make-u....vector ...)) (scheme-foo bar)
There are a lot of C functions I need to use that take arguments int*, short*, ...
I would prefer to not change all these C bindings, and somehow magically have a Scheme function that given: (uber-magic bar) returns me a int* corresponding to where the data is stored in u32-vector bar.
Thanks!
Afficher les réponses par date
On 17-Apr-09, at 12:19 AM, lowly coder wrote:
Hi!
This is a different question from my previous silly question.
All though it's really cool that I can take a C function with signature: void foo(int *); and in scheme land create a (scheme-foo) so that I can do:
(define bar (make-u....vector ...)) (scheme-foo bar)
There are a lot of C functions I need to use that take arguments int*, short*, ...
I would prefer to not change all these C bindings, and somehow magically have a Scheme function that given: (uber-magic bar) returns me a int* corresponding to where the data is stored in u32- vector bar.
That would be problematic because objects in the Scheme heap, including vectors, can be moved by the garbage collector. So a C pointer to an element of a u32vector could become stale (dangling pointer) at any moment. The only way this could work is to allocate a "still" vector. But all of this is seriously asking for trouble (the pointer will be a dangling pointer when the still object is reclaimed).
Marc
I'm really glad you mentioned this .... I got to this point:
(include "gl-header.scm")
(c-declare #<<c-declare-end
#include <GL/gl.h>
c-declare-end
)
(define u32-vector->uint*
(c-lambda (scheme-object) GLuint* "___result = ___CAST(GLuint*,&___FETCH_U32(___BODY(_\ __arg1),___INT(0)));"))
... and yeah, now I'm going to scratch it. Wasn't aware the gc moved stuff around. Thanks! I can only imagine how fun this bug would have been to debug.
On Thu, Apr 16, 2009 at 9:30 PM, Marc Feeley feeley@iro.umontreal.cawrote:
On 17-Apr-09, at 12:19 AM, lowly coder wrote:
Hi!
This is a different question from my previous silly question.
All though it's really cool that I can take a C function with signature: void foo(int *); and in scheme land create a (scheme-foo) so that I can do:
(define bar (make-u....vector ...)) (scheme-foo bar)
There are a lot of C functions I need to use that take arguments int*, short*, ...
I would prefer to not change all these C bindings, and somehow magically have a Scheme function that given: (uber-magic bar) returns me a int* corresponding to where the data is stored in u32-vector bar.
That would be problematic because objects in the Scheme heap, including vectors, can be moved by the garbage collector. So a C pointer to an element of a u32vector could become stale (dangling pointer) at any moment. The only way this could work is to allocate a "still" vector. But all of this is seriously asking for trouble (the pointer will be a dangling pointer when the still object is reclaimed).
Marc
If you want to play with fire :D. Only use in a c-fonction where the pointer won't persist in c-land.
(c-declare #<<c-declare-end
typedef ___U32* U32PTR;
___SCMOBJ SCMOBJ_to_U32PTR (___SCMOBJ src, U32PTR *dst) { ___SCMOBJ ___temp; // for U32VECTORP ___SCMOBJ ___err = ___FIX(___NO_ERR); if (!___U32VECTORP(src)) ___err = ___FIX(___UNKNOWN_ERR); else { *dst = ___CAST(___U32*,___BODY_AS(src,___tSUBTYPED)); } return ___err; }
#define ___BEGIN_CFUN_SCMOBJ_to_U32PTR(src,dst,i) \ if ((___err = SCMOBJ_to_U32PTR (src, &dst)) == ___FIX(___NO_ERR)) { #define ___END_CFUN_SCMOBJ_to_U32PTR(src,dst,i) }
#define ___BEGIN_CFUN_U32PTR_to_SCMOBJ(src,dst) \ if ((___err = ___FIX(___UNKNOWN_ERR)) == ___FIX(___NO_ERR)) { #define ___END_CFUN_U32PTR_to_SCMOBJ(src,dst) }
#define ___BEGIN_SFUN_U32PTR_to_SCMOBJ(src,dst,i) \ if ((___err = U32PTR_to_SCMOBJ (src, &dst)) == ___FIX(___NO_ERR)) { #define ___END_SFUN_U32PTR_to_SCMOBJ(src,dst,i) }
#define ___BEGIN_SFUN_SCMOBJ_to_U32PTR(src,dst) \ { ___err = ___FIX(___UNKNOWN_ERR); #define ___END_SFUN_SCMOBJ_to_U32PTR(src,dst) }
c-declare-end )
(c-define-type U32PTR "U32PTR" "U32PTR_to_SCMOBJ" "SCMOBJ_to_U32PTR")