If I have a c function that takes a pointer to an ...
# kotlin-native
k
If I have a c function that takes a pointer to an uninitialized struct and populates that reference with a value:
Copy code
struct Foo foo;
init_foo(&foo);
return foo;
Is this the right way to perform the same task using cinterop?
Copy code
val foo = Foo(NativePtr.NULL)
init_foo(foo.ptr)
return foo
I'm thinking I may have to mess around with StableRef but I'm not sure
l
I don’t believe Kotlin/Native allows you to use the NativePtr constructor (IDE doesn’t show this, but you get an error when compiling). The way I’ve been doing this is to use some sort of alloc (Arena, nativeHeap, etc) to create your Foo.
k
Unfortunately the library I'm interfacing with is expected to create the foo instance and allocate the memory. Am I still required to needlessly allocate this memory solely to get a pointer?
l
Make sure not to use memScoped if you plan to return the value, since memScoped will free the memory. I’d recommend creating an Arena for this, and set
val foo = arena.alloc<Foo>()
k
I don't manage the allocation. Let me read up on arena but I don't think its what I need
l
In the C code you gave, the library doesn’t allocate the Foo. The Foo object gets put on the stack.
k
I see. My C knowledge is certainly not good!
l
I don’t know that there’s a way to stack allocate in Kotlin right now (aside from a really hacky alloca(size).reinterpret<Foo>() that is also quite dangerous). I’d just use an arena for now.
It’s also easy to get confused when dealing with libraries that take a double ptr, like if the signature was init_foo(Foo**). In this case, you’d have
Copy code
val fooPtr = arena.allocPointerTo<Foo>()
init_foo(fooPtr.ptr)
val foo = fooPtr.pointed
k
I ended up doing
Copy code
val arena = Arena()
val ring: io_uring = arena.alloc()
io_uring_queue_init(ring = ring.ptr)
return URing(ring, arena)
Where the
URing
wrapper is closeable