It's okay, this isn't urgent (as in done in the next 24 hours or die; more like I need to finish it in the next few days).
Here's a concerete problem I'm running into:'
;(define gl/GenTextures (c-lambda ( GLsizei scheme-object ) void "glGenTextures(___arg1,\ ___CAST(GLuint*,&___FETCH_U32(___BODY(___arg2),___INT(0))));"))
(define gl/TexImage2D (c-lambda ( GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum\ scheme-object ) void "glTexImage2D(___arg1, ___arg2, ___arg3, ___arg4, ___arg5, ___arg6\ , ___arg7, ___arg8, ___CAST(GLvoid*,&___FETCH_U32(___BODY(___arg9),___INT(0))));"))
the commented out gl/GenTextures work fine
the problem is with gl/TexImage2D ... I don't know, until run time, what type of *vector I want to pass to it. Do I need to create a separate gl/TexImage2D for each? I looked at gambit.h, grepping for ___FETCH ... and I got: #define ___FETCH_S64(base,i)*(___CAST(___S64*,base)+(i)) #define ___FETCH_U64(base,i)*(___CAST(___U64*,base)+(i)) #define ___FETCH_S32(base,i)*(___CAST(___S32*,base)+(i)) #define ___FETCH_U32(base,i)*(___CAST(___U32*,base)+(i)) #define ___FETCH_S32(base,i)___CAST_S32(___FETCH_U32(base,i)) #define ___FETCH_U32(base,i)(((i)&1) \ #define ___FETCH_U32(base,i)(((i)&1) \ #define ___FETCH_S16(base,i)*(___CAST(___S16*,base)+(i)) #define ___FETCH_U16(base,i)*(___CAST(___U16*,base)+(i)) #define ___FETCH_S16(base,i)___CAST_S16(___FETCH_U16(base,i)) #define ___FETCH_U16(base,i)(((i)&1) \ #define ___FETCH_U16(base,i)(((i)&1) \ #define ___FETCH_S16(base,i)(((i)&1) \ #define ___FETCH_U16(base,i) \ #define ___FETCH_U16(base,i) \ #define ___FETCH_S8(base,i)*(___CAST(___S8*,base)+(i)) #define ___FETCH_U8(base,i)*(___CAST(___U8*,base)+(i)) #define ___FETCH_S8(base,i)___CAST_S8(___FETCH_U8(base,i)) #define ___FETCH_U8(base,i) \ #define ___FETCH_U8(base,i) \ #define ___FETCH_U8(base,i) \ #define ___FETCH_U8(base,i) \ #define ___BIGAFETCH(base,i) ___FETCH_U32(base,i) #define ___BIGAFETCHSIGNED(base,i) ___FETCH_S32(base,i) #define ___BIGAFETCH(base,i) ___FETCH_U64(base,i) #define ___BIGAFETCHSIGNED(base,i) ___FETCH_S64(base,i) #define ___BIGMFETCH(base,i) ___FETCH_U16(base,i) #define ___BIGMFETCH(base,i) ___FETCH_U32(base,i) #define ___FRAME_FETCH_RA \
is there a generic FETCH instruction that says: "I don't care what kind of *vector you pass me, I'll just give you a void* pointing to the first element" ?
Thanks!
On Thu, Apr 16, 2009 at 9:47 PM, Marc Feeley feeley@iro.umontreal.cawrote:
On 17-Apr-09, at 12:41 AM, lowly coder wrote:
I probably deserve to be shot for this, but ...
I need this only when wrapping a single C call, and AFAIK, the gambit GC does not run while I'm inside a C function.
Does gambit support things like:
(disable-GC) (... unsafe call involving taking int* of a u32-vector) (enable-GC)
Thanks!
No it doesn't because just about everything (including function calls) can allocate heap memory, and cause a GC. However, currently the GC does not run concurrently with the main program, so it is possible (currently) to pass a (possibly) movable u32vector to a c-lambda, as a "scheme-object", and then cast that in the C code to a ___U32* using the ___BODY macro. It shouldn't be too hard to simplify all of this with a c-define-type with scheme-to-c and c-to-scheme converter functions.
Too late for me to do that now. Jérémie can you help?
Marc
Afficher les réponses par date
I believe a better way to solve these issues is to create a generic library for allocating C memory.
------------
(define alloc-u8 (c-lambda (int) u8* "___result_voidstar = malloc(___arg1*sizeof(unsigned char));"))
(define u8*-ref (c-lambda (u8* int) int "___result = ___arg1[___arg2];"))
(define u8*-set! (c-lambda (u8* int int) void "___arg1[___arg2] = ___arg3;"))
(define (u8vector->u8* v) (let* ((len (u8vector-length v)) (c-buffer (alloc-u8 len))) (let loop (i 0) (if (< i len) (begin (u8*-set! c-buffer i (u8vector-ref v i)) (loop (+ i 1))) c-buffer))))
(define free (c-lambda ((pointer void #f)) void "free((void*)___arg1);"))
-----------
void do_something_with_u8(unsigned char *data) { ... }
(define %%do-something-with-u8 (c-lambda ((pointer unsigned-char)) void "do_something_with_u8"))
(define (do-something-with-u8 v) (let ((buf (u8vector->u8* v))) (%%do-something-with-u8 buf) (free buf)))
----------------
I'm working on automatically generating this interface for all the possible types. This lets you access all FFI's without the need to change C code. Unfortunately, it requires allocation for every call, but there are ways to optimize this. That code is completely untested and just wanted to give you the idea.
- James