I'm wrapping a C function that takes a pointer as an argument and treats it either as an int pointer, a float pointer, or an array of ints or floats, depending on another argument. The function is part of renderer in a game, and is called many (60+) times per second.
So with that said, I know I can use _list
to pass array type argument, but
it fragments the heap? If I understand it correctly, racket calls malloc
before each invocation, and free
right after
it needs a specific type, so I would then have to create 2 functions (one for _int
, one for _float
), which wouldn't be ideal
I stumbled across https://docs.racket-lang.org/foreign/C_Array_Types.html , and it seems exactly what I want -- both more efficient ("The array is not copied; the Racket representation is backed by the underlying C representation") and also suitable for more than one type ("it can have a different element type as long as that type matches the layout of the expected type").
Problem is, I can't seem find a way how to construct it from Racket side? These all statements return #f
, and I'm out of ideas
#lang racket
(require ffi/unsafe)
(displayln (array? (make-array-type _float 5)))
(displayln (array? (_array _float 5)))
(displayln (array? (malloc (_array _float 5))))
(displayln (array? (malloc (make-array-type _float 5))))
The make-array-type
and _array
functions create C types, which are plain Racket run-time values that describe how to convert kinds of values to and from C-level representations: for example, _unt8
is a C type. The predicate array?
recognizes actual values that are represented with an _array
-based C type, not the C type itself.
As far as constructing an array value, the docs say:
Since an array is treated like a struct, casting a pointer type to an array type does not work. Instead, use ptr-ref with a pointer, an array type constructed with _array, and index 0 to convert a pointer to a Racket representation that works with array-ref and array-set!.
Here's how that works in practice—the docs could use an example:
#lang racket
(require ffi/unsafe
rackunit)
(define 5floats (_array _float 5))
(check-true
(array? (ptr-ref (malloc 5floats) 5floats)))
For future reference, the Racket community is much more active on the racket-users mailing list and Slack than on Stack Overflow.