;;;; ((Ptr T) p) and (slice-from p n) together: the bytes of one array read as ;;;; another element type, the way a C void * or a (Ptr u8) pixel buffer is ;;;; read as the structs it holds. (defstruct Rgba [r u8 g u8 b u8 a u8]) (defonce bytes [8 u8]) (defn sum [s [const Rgba]] i32 (let [acc 0] (dotimes [i (length s)] (set acc (+ acc (i32 (.g (at s i)))))) acc)) (defn main [] () (dotimes [i 8] (set (at bytes i) (u8 (+ i 1)))) ;; Eight bytes are two Rgba. The count is an i64, not an i32. (let [p ((Ptr Rgba) (addr (at bytes 0))) n (i64 2) px (slice-from p n)] (println (length px)) ; 2 (println (.r (at px 0))) ; 1 (println (.a (at px 1))) ; 8 ;; A write through the cast pointer is a write to the bytes. (set (.b (at px 1)) 70) (println (at bytes 6))) ; 70 ;; Adding const is allowed, and the slice keeps it. (let [c ((Ptr const Rgba) (addr (at bytes 0)))] (println (sum (slice-from c (u8 2))))) ; 8 ;; And back: the struct pointer read as bytes again. (let [p ((Ptr Rgba) (addr (at bytes 0))) b ((Ptr u8) p)] (println (deref b)) ; 1 (println (length (slice-from b 8))))) ; 8