I have to call an external API using C arrays from Nim seq[]. The API is using the array content for the duration of the call. What would be the safest and future proof way of doing it?
1. Share seq[] private array for the duration of the call
var s: seq[Obj] # contains the data that must be sent to the external API
api_call(s.len.cuint, addr(s[0]))
2. Manage a temporary unchecked array
var s: seq[Obj]
var
arrPtr = alloc(s.len * sizeof(Obj))
arr = cast[ptr UncheckedArray[Obj]](arrPtr)
for i, v in s:
arr[i] = v
let a = api_call(s.len.cuint, arr)
dealloc arrPtr
I don't care about performance here but the more future proof and safest code. Version #1 is shorter to write and less prone to forgetting deallocating the memory of version #2. But it seems to me that with version #2, at least I don't depend on how memory is used by seq[].
What would you recommend?
Like I said, my goal is to write safe code and not rely on internal hacks. Optimizations are not my concern, for the moment, as I delegate them to improvements to the Nim compiler.
Solution #1 relies on knowledge of seq[] internals, and even if it's widely used, I'm reluctant to using it in my code. What are the chances that seq[] is optimized in Nim v4 to balance its internal data structure between the legacy array and an optimized structure when many element moves occur, all decided by the compiler?
It's not a hack, I don't know where it is documented, but
This openarray usage with C bindings would be useful for the API I’m working with; but I’d need to see it documented. If it’s not documented then it’s just a side effect of the implementation, which could change at any time.
I suppose this is another way of asking whether Nim’s C backend has a documented ABI.