I have a list that I want to convert into a C array. _array/list looks promising, as "the Racket representation is a list". But how exactly can I convert my list into a C array?
I believe part 2 has an example.
Thank you, that was a very interesting read. Unfortunately, I couldn't apply the example in the blog. This is the function I want to call (from the raylib wrapper):
(DrawLineStrip points pointCount color) → _void
points : (_pointer-to _Vector2)
pointCount : _int
color : _Color
Now in order to create the points parameter I need to make use of some _array function, correct? I've played a little with it and it doesn't really make sense:
> (define bar (_array _int 5))
> (array? bar)
#f
> (array-set! bar 0 7)
; array-length: contract violation
; expected: array?
; given: #<compound-ctype>
; [,bt for context]
> (array-type bar)
; array-type: contract violation
; expected: array?
; given: #<compound-ctype>
; [,bt for context]
>
Why does this not work? The documentation for _array states:
Creates an array type whose Racket representation is an array that works with array-ref and array-set!.
That doesn't seem to be correct. What am I missing?
From the documentation of
I see that Vector2 is a struct consisting of two floats.
(struct Vector2 (x y)
#:constructor-name make-Vector2)
x : _float
y : _float
So I think, you can pass (vector (make-Vector2 1. 2.) (make-Vector2 3. 4.)) for the first argument points.
Unfortunately, that doesn't work:
cpointer-accessor: contract violation
expected: cpointer?
given: '#(#<cpointer> ...
In the meantime I've learned about cvector, which didn't work either:
cpointer-accessor: contract violation
expected: cpointer?
given: #<cvector>
Edit: I found the cvector-ptr procedure, which did the trick ![]()
_array creates a ctype? not an array. Either the array is allocated by the C library, or you can allocate it with malloc and then follow this guidance from the make-array-type docs:
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!.
Something like this should work:
(define _shape-array-1d (_array _int 1))
(define shape (malloc _shape-array-1d))
(array-set! (ptr-ref shape _shape-array-1d 0) 0 10)
(array-ref (ptr-ref shape _shape-array-1d 0) 0)
This is from some example code I had commented out because dealing with array types in the FFI is a pain! There are ways to avoid having to do this manually, like letting the fun auto-convert from vectors for you or just using pointers.
I think I get the idea of how arrays work, but I haven't implemented it. Instead I went for cvector. This is roughly what I'm doing:
(define (draw-outline list-of-Vector2 color)
(let ((cvec (list->cvector list-of-Vector2 _Vector2)))
(DrawLineStrip (cvector-ptr cvec) (cvector-length cvec) color)))
soegaard said I can use a vector, but I couldn't make that work.
One question remains, just out of curiosity: Is cvector implemented with arrays under the hood? Or are a they implemented independently?