can someone help me out with the `CValue` concept ...
# kotlin-native
c
can someone help me out with the
CValue
concept and passing structs by reference to C functions?
when I have a C function like
Copy code
void do_something(struct_t *boop)
I can pass in the result of
cValue<struct_t>()
into the function, but any modifications done to the struct are not carried over If I use
memScoped
and pass the
ptr
value in, the same happens. If I dynamically allocated with
alloc<struct_t>()
THEN it works
I guess what I want is to figure out what the
&structVar
equivalent would be in kotlin
https://kotlinlang.org/docs/tutorials/native/mapping-struct-union-types-from-c.html has been my bible, but it doesn't explain how to do it without dynamic allocation
d
If I use
memScoped
and pass the
ptr
value in, the same happens.
Should have worked.
That's the de facto way.
You have to call
alloc<...>
in a
memScoped
block.
c
so! I've gone with something I hope isn't filthy
Copy code
class MyStructWrapper {
   private val arena = Arena()
   private val myStruct = arena.alloc<my_struct_t>().ptr

   fun doSomething() = c_api_do_something(myStruct)
}
it works but not sure if I'm just pouring memory out everywhere
my understanding is the arena will deallocate when the containing object is deallocted
d
You have to manually free the arena.
Copy code
memScoped {
   val structVar = alloc<struct_t>()
   doSomething(structVar.ptr)
   // Do stuff with structVar
}
// structVar is freed.
c
hmm, so what would be the recommended way to have a dynamically allocated object be a field member of something that wasn't
or, 😅 if you were going to do something similar to the code snippet I posted, how would you go about it?
d
Ideally, you would just copy it into a Kotlin object.
Are you going to be rewriting the value or just write once and use many?
c
rewriting unfortunately, I think that's where the problem is
d
Hmm, I guess you can use
nativeHeap
.
You only need one struct right?
c
yeah
how would I go about using nativeHeap? (cheers for your help dude, I can't imagine what kind of lemon soaked razor blades you've crawled over to get to this point!)
d
Haha, yeah it's been fun.
Then
nativeHeap
is the way to go. Just don't forget to call free when you're done with the class. Have a
Closeable
interface or something.
val struct = nativeHeap.alloc<struct_t>
nativeHeap.free(struct)
when you're done.
c
oki doki 💪 I'll see if I can't work that in some how
as it happens, I'm having a little play about with wrapping Cairo - https://cairographics.org/samples the object I'm messing about with is a
cairo_matrix_t
. All my unit tests were generating the correct output per-each sample, except the image pattern one
I've wrapped the cairo_matrix_t variable in a
CairoMatrix
class, but I couldn't figure out how get things working without dynamic allocation which is doing my nut in! But it's only a play thing for me right now, so I'll persevere... I haven't even gotten to the lemon soaked razors yet 😂
d
Ah I see. Representing stuff like that in Kotlin can be a bit awkward. Especially when there's stack allocation involved.
I'm guessing you have a
CairoSurface
class?
c
I do, but fortunately all the allocation is handled by the C API (but I do have a destroy method)
d
I guess you'll be giving all your objects destroy methods.
c
I miss garbage collection all of a sudden!
so stack allocation isn't directly mappable to kotlin?
d
Not really. You can always make your own stack.
Allocate a big blob and the sub allocate from it when you need to.
c
cheers dude, this has been really useful- I'm kind of feeling my way through things at the minute, not everything has been super intuitive, but I am seeing results and making progress. Understanding the mechanics more and things to look out for is going to be massively helpful
d
No problem
s
Passing
CValue
for pointer parameter creates a temporary copy of it, because
CValue
is immutable. Taking
.ptr
on
CValue
does the same for the same reason.
I’ve wrapped the cairo_matrix_t variable in a
CairoMatrix
class, but I couldn’t figure out how get things working without dynamic allocation
Does anything prevent you from having
val value: CValue<cairo_matrix_t>
in your
CairoMatrix
class?
d
He needs to be able to rewrite the value and
CValue<... >
is immutable.
s
Then mutable property (
var
) could be used.
d
How are `CValue`s stored? Are they like value types? Or is does it use
nativeHeap
underneath and free the memory when garbage collected?
s
Does it matter for this purpose?
d
Kind of, it would be a shame to have to call
nativeHeap.alloc<...>
every time the value needs changing (or reading) when a single allocation would do.
s
CValue
is stored in the heap. You can’t reuse the same memory for a new value.