I found this previous post about passing a Nimrod array to a C param expecting a pointer to the first element:
http://forum.nimrod-lang.org/t/51
So without the template wizardry, I concluded that to populate the following member of a C type:
int *map;
I use the following:
cast[ptr cint](addr(myArray))
where myArray is an array of type [12, cint].
Now, how do I get such a value back from an object returned from C? I get the length n, as well as the array pointer map. I have tried
var map = cast[ptr [obj.n, cint]](obj.map)
But gives me compile error "type expected".
Or is there a good example of a library that wraps array-pointer calls that I should look at?
Thanks
If you have a C pointer to an array of a length not known at compile time, you cannot cast it to a pointer of a fixed length array. You get a compile error because obj.n cannot be evaluated at compile time. What you're returning is a pointer to an int and you emulate that in Nim with a pointer to an unchecked array. The following code shows how and also provides a wrapper for index operations that performs bounds checking at runtime.
type CArray*{.unchecked.}[T] = array[0..0, T]
type CPtr*[T] = ptr CArray[T]
type SafeCPtr*[T] =
object
when not defined(release):
size: int
mem: CPtr[T]
proc safe*[T](p: CPtr[T], k: int): SafeCPtr[T] =
when defined(release):
SafeCPtr[T](mem: p)
else:
SafeCPtr[T](mem: p, size: k)
proc safe*[T](a: var openarray[T], k: int): SafeCPtr[T] =
safe(cast[CPtr[T]](addr(a)), k)
proc `[]`*[T](p: SafeCPtr[T], k: int): T =
when not defined(release):
assert k < p.size
result = p.mem[k]
proc `[]=`*[T](p: SafeCPtr[T], k: int, val: T) =
when not defined(release):
assert k < p.size
p.mem[k] = val
var t: array[100, cint]
var a = safe(t, 50)
t[17] = 314
echo(a[17])
Many thanks, Jehan.
I hadn't even heard of an unchecked pragma, I guess that with array, seq and openarray I just wasn't looking out for another option.
I've stuck with the unsafe version for my current tinkering, and I figure that a two dimensional C Array, such as:
int (*array)[3]
can be represented using your types as
CPtr[array[3, cint]]