[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: ffi for glutInit
From: |
Aleix Conchillo Flaqué |
Subject: |
Re: ffi for glutInit |
Date: |
Sat, 4 Aug 2012 09:19:17 -0700 |
Thank you both guys. Mark's code works perfectly, I can open a window
with glut and make some gl code work, great!
However, after your recommendations I've started with the wrapper in
C, let's see how far I get.
Thanks,
Aleix
On Thu, Jul 26, 2012 at 9:33 AM, Mark H Weaver <address@hidden> wrote:
> On 07/25/2012 06:19 PM, Aleix Conchillo Flaqué wrote:
>>
>> I have started working on bindings for OpenGL and GLUT.
>>
>> https://github.com/aconchillo/guile-gl
>
>
> Excellent! :-)
>
>
>> Now, I'm stuck with glutInit. The signature of the function is like this:
>>
>> glutInit(int *argc, char **argv);
>>
>> See: http://www.opengl.org/resources/libraries/glut/spec3/node10.html
>>
>> I don't really know how to do the char** part, so I need some help here.
>>
>> For the user, the guile procedure will simply look like (glutInit) and
>> internally (command-line) would be ideally used to construct the
>> char**, etc.
>
>
> First of all, I should mention that although the dynamic FFI is very
> convenient, it is not necessarily the best way to write a robust and
> efficient library wrapper. Most notably, things like preprocessor macros
> are not handled by the FFI, and there is currently a non-trivial overhead
> for each call through the FFI. This overhead arises because the FFI does
> not generate native code wrappers, but instead each wrapper has a loop that
> iterates over the list of arguments and argument types, and constructs the
> stack frame one argument at a time before calling the C function. This is
> probably not significant in most cases, but for small and fast C functions
> that might be used within an inner loop with a high iteration count, you'd
> probably want to write the wrapper in C.
>
> In this case, we have the problem that libffi, which is the basis for
> Guile's dynamic FFI, does not support array types. However, in practice we
> can pretend that arrays and structs have the same layout, and I suspect that
> this works on most architectures. Here's one way to do it:
>
> (use-modules (system foreign))
>
> (define libglut-obj (dynamic-link "libglut"))
>
> ;; (glut-init args), where args is the complete list of command
> ;; arguments (starting with the program name), calls glutInit and
> ;; returns the (possibly) modified list of arguments.
> (define glut-init
> (let ((foo-init-raw (pointer->procedure
> void
> (dynamic-func "glutInit" libglut-obj)
> (list '* '*)))
> (saved-c-strings '()))
> (lambda (args)
> (let* ((num-args (length args))
> (c-strings (map string->pointer args))
> (argcp (make-c-struct (list int)
> (list num-args)))
> (argv (make-c-struct (make-list (+ 1 num-args) '*)
> (append c-strings
> (list %null-pointer)))))
> (set! saved-c-strings (append c-strings saved-c-strings))
> (foo-init-raw argcp argv)
> (let ((argc (car (parse-c-struct argcp (list int)))))
> (map pointer->string
> (parse-c-struct argv
> (make-list argc '*))))))))
>
> ;; Example usage
> (set-program-arguments (glut-init (program-arguments)))
>
> Note the use of 'saved-c-strings' to keep a reference to all of the C string
> buffers that we ever pass to 'glutInit'. This is important because the glut
> docs specify that 'glutInit' wants the original unmodified 'argv' passed to
> 'main', which means that it can assume that the strings will never be freed.
> 'string->pointer' returns a C string buffer managed by the garbage
> collector, which means that the string may be freed unless the GC can see a
> pointer to the _beginning_ of the string.
>
> Happy hacking!
>
> Mark
>
>
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- Re: ffi for glutInit,
Aleix Conchillo Flaqué <=