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.