I suggest you have your function return a ptr to the first element and a length 
instead and make sure that while your function is running a variable holds on 
the seq so it's not garbage collected.

A seq at a low-level is:

  * 2 ints (C int_64t on 64-bit arch) for tlength and reserved space
  * a pointer to a contiguous heap-allocated array of elements



See: 
[https://github.com/nim-lang/Nim/blob/721bf7188bfff3a3ae1db44bece57cca3dfe8461/lib/system.nim#L502-L508](https://github.com/nim-lang/Nim/blob/721bf7188bfff3a3ae1db44bece57cca3dfe8461/lib/system.nim#L502-L508)
    
    
    when not defined(JS) and not defined(gcDestructors):
      type
        TGenericSeq {.compilerproc, pure, inheritable.} = object
          len, reserved: int
          when defined(gogc):
            elemSize: int
        PGenericSeq {.exportc.} = ptr TGenericSeq
    
    
    Run

This changes a bit when using destructors or Javascript or the Go GC.

The way to use seq in FFI is
    
    
    ## raw example
    
    let a = @[1, 2, 3, 4, 5]
    
    let a_ptr = a[0].unsafeAddr # cast to ptr UncheckedArray if you want array 
indexing
    # if a is a var a[0].addr is enough
    
    
    ## C Interface function
    
    proc foo(a: seq[int]): tuple[p: ptr int, len: int] {.exportc.} =
      result = (a[0].unsafeAddr, a.len)
    
    
    Run

Reply via email to