At Fri, 31 Jul 2020 17:05:27 -0400, Hendrik Boom wrote: > For example, there's glGetCompressedTexImageARB. It receivees a > pointer to an image area and fills it in with a compressed image. > According the the Racket C interface, the way to write this > would be: > > (define-gl glGetCompressedTexImageARB 2 > ( (target : _int32) > (level : _int32) > (img : _pointer/intptr) > -> _void -> img) > (->> exact-integer? exact-integer? gl-pointer?) > check-gl-error)
If I understand correctly that `target` and `level` provide enough information to specify how big `img` should be, then I agree that something analogous to (_fun (target : _int32) (level : _int32) (img : _pointer/intptr = (malloc (COMPSIZE target level))) -> _void -> img) is a fine way to wrap the function. But when I work at the level of C APIs, I usually prefer this kind of interface: > But the old binding instead used > ( (target : _int32) > (level : _int32) > (img : _pointer/intptr) > -> _void) > > In other words, it ignored the fact that img is used as an output > parameter. Although, when I use this kind of binding, I have to know which pointers must already be filled with information when I pass it to the function versus which ones will be filled by the function, exposing the pointer to to-be-filled memory gives me control over the way that the memory. It also avoids having to specify anything about the deallocation rules of the result of a binding (e.g., whether it needs to be explicitly freed). Still, I can also see the advantage of building allocation into the wrapper to make clear that the argument corresponds to to-be-filled memory. Perhaps it depends on the overall shape of the API. If the API is going to be wrapped further to make it more Rackety, then I'd go for less wrapping at the immediate FFI bindings. If the API looks fairly Rackety with a few tweaks to arguments and results, then I'd favor more wrapping in the bindings. I think the old GL binding was in the former camp: it first exposed GL functions in as raw as possible form, and then wrapped those with a higher-level library. > Now what should I do with this? As I said there are very many such > functions. It's not an isolated case. > > Are all these glGet functions simply something that never happened to > get used in Racket code so no one noticed the discrepancy? > Is there some idiom in Racket programming where all this just works > anyway? > Is there some efficency reason for not recognising output parameters? > Do they parhaps cause new storage allocation every time they are called? I wouldn't say there's any "discrepancy" in `img` being an output argument instead of an input argument. This kind of input--output distinction doesn't exist at C ABI level, so no distinction is inherently necessary in the FFI binding. Certainly, though, you can create FFI wrappers that better reflect the intent of parameters than the ABI-level types do. You're right that exposing details like to-be-filled pointer arguments usually offers the best available performance, but it's not always an issue. This example looks like one where callers will practically always allocate the destination memory just before calling the function, so it will work out the same. Matthew -- You received this message because you are subscribed to the Google Groups "Racket Users" group. To unsubscribe from this group and stop receiving emails from it, send an email to racket-users+unsubscr...@googlegroups.com. To view this discussion on the web visit https://groups.google.com/d/msgid/racket-users/20200801114806.1d8%40sirmail.smtps.cs.utah.edu.