From: "Aleix Conchillo Flaqué" <aconchillo@gmail.com>
To: Mark H Weaver <mhw@netris.org>
Cc: guile-devel@gnu.org
Subject: Re: ffi for glutInit
Date: Sat, 4 Aug 2012 09:19:17 -0700 [thread overview]
Message-ID: <CA+XASoUHGbEB0Sqb55B+Ep4S+KEUi21iEyyLZdBCvXUdfqJkaQ@mail.gmail.com> (raw)
In-Reply-To: <50117174.6040104@netris.org>
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 <mhw@netris.org> 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
>
>
next prev parent reply other threads:[~2012-08-04 16:19 UTC|newest]
Thread overview: 8+ messages / expand[flat|nested] mbox.gz Atom feed top
2012-07-25 22:19 ffi for glutInit Aleix Conchillo Flaqué
2012-07-26 2:30 ` Nala Ginrut
2012-07-26 15:46 ` Aleix Conchillo Flaqué
2012-07-26 16:33 ` Mark H Weaver
2012-07-26 16:39 ` Mark H Weaver
2012-07-26 18:07 ` Nala Ginrut
2012-08-04 16:19 ` Aleix Conchillo Flaqué [this message]
2013-01-21 12:04 ` Andy Wingo
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
List information: https://www.gnu.org/software/guile/
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=CA+XASoUHGbEB0Sqb55B+Ep4S+KEUi21iEyyLZdBCvXUdfqJkaQ@mail.gmail.com \
--to=aconchillo@gmail.com \
--cc=guile-devel@gnu.org \
--cc=mhw@netris.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).