type
TRow = seq[string]
TRows = seq[TRow]
proc dbGetRowsCb(arr: pointer; colCount: int32; values, columns: cstringArray): int32 {.cdecl.} =
var cols:TRow
for i in 0..<colCount:
cols.add($values[i])
var arr = cast[ptr TRows](arr)
arr[].add(cols)
return 0
proc dbGetRows*(q:string): TRows =
var err:cstring=""
var arr: TRows
discard db.exec(q, dbGetRowsCb, result.addr, err)
if err != "":
echo err
free err
In the dbGetRowsCb proc if i change the lines
var arr = cast[ptr TRows](arr)
arr[].add(cols)
to
var arr = cast[ptr TRows](arr)[]
arr.add(cols)
The sequence returned by dbGetRows is empty. Why??? Is it because the original sequence, once dereferenced, is copied to "var arr", hence "cols" is not added to it but to a copy which is deleted once the proc returns?Hello @phoenix27,
Sorry to be straightforward, but you are doing all wrong ! ;-)
If I'm not mistaken, the seq object looks like this (https://github.com/nim-lang/Nim/blob/646bd99d461469f08e656f92ae278d6695b35778/lib/system/seqs_v2.nim#L20) :
type
NimSeqPayload[T] = object
cap: int
data: UncheckedArray[T]
NimSeqV2*[T] = object # \
# if you change this implementation, also change seqs_v2_reimpl.nim!
len: int
p: ptr NimSeqPayload[T]
So if you cast a seq to a pointer, you will not get at all the buffer ! In fact, you get a pointer that points to something totally different (and you risk a SIGESEGV)
The prefered way to use a seq with c is :
You can also use an array. Contrary to a seq, it doesn't encapsulate a buffer:
var arr: array[64, int]
doAssert(addr arr == addr arr[0])
var list = newSeq[int](64)
doAssert(addr list != addr list[0])
If you want to allocate, or grow/shrink a hap buffer in c, you won't be able to use seq effiently or easily (Unfortunatly, seq API don't provide a way to transform a heap buffer into a seq without copy. ).
I have found the result variable it a little "touchy" sometimes.
In what way?
Is it because the original sequence, once dereferenced, is copied to "var arr", hence "cols" is not added to it but to a copy which is deleted once the proc returns?
Yup, spot on