Oh, almost forgot, but let's have a look at `ptr UncheckedArray[byte]` as Araq 
suggested. In C there really isn't any difference between a pointer to a single 
element, and a pointer to a series of elements. If you use square brackets on a 
pointer it is simply a shortcut for doing pointer arithmetic, no checking goes 
on under the hood to verify if you are actually doing this a something which is 
intended to be a series of elements. In Nim however the type system is much 
stricter than in C, and `ptr byte` and `ptr UncheckedArray[byte]` is how we 
make this distinction. `ptr byte` in Nim is always a pointer to a single byte, 
and as you discovered the only way to get the "next element" if your `ptr byte` 
actually points to the first element in an array of bytes is to cast it back 
and forth between a pointer type and a number while doing arithmetic on the 
numerical value. This is very inconvenient. So the way you're supposed to 
handle arrays coming from C is with `ptr UncheckedArray[byte]`. This type is 
simply a pointer to a series of bytes of an unknown length, so it isn't checked 
for out of bound access. You will see that this type actually supports the 
square bracket notation to fetch elements, but keep in mind that we need to 
check the bounds ourselves. In my previous answer I mentioned how we could 
populate a sequence or string in Nim, either through allowing the C API to 
write directly into a pre-allocated string, or by copying over the bytes after 
the fact. This would create a managed structure with bound checks and 
everything. Using `UncheckedArray` we accept the burden of working with a C 
data type and have to free the memory ourselves and deal with bound checks 
ourselves.

Personally I'd really like Nim to add a `CheckedArray` type which had a generic 
type and a generic length field for an even nicer API to C types (as many of 
them come with some form of length). But if you're able to it's always better 
to create proper Nim types instead.

Reply via email to