Where can I find an example of allocating an array...
# kotlin-native
j
Where can I find an example of allocating an array of structs in order to pass a
CValuesRef
to the leading item + item count to a C function? I've done with things like ByteArray where I can call
refTo(0)
but I don't see an explanation or example of how to do this with a struct type.
j
thanks. this will unblock me, i think, but it's far from ideal...
i'm also getting structs back from a call to a C function so i have to copy their contents into each index which is not pretty
Copy code
val args = allocArray<Thing>(4)
    arg0.useContents {
      args[0].tag = tag
      args[0].u.int32 = u.int32
      args[0].u.float64 = u.float64
    }
    // etc.
and sure I can put it behind a helper function, but it's still very awkward
m
But C cannot return array of structs by values, right? So it's all pointer based ?
Copy code
void myfunction(struct thing * input_output_param, int *size)
Then you can use the same allocated array for both input + output maybe?
g
Maybe this can be helpful? • https://github.com/Durun/vst3kotlin/blob/f1082278b6c763fbebb4318c83f7aecdf501e233/[…]n/kotlin/durun/vst3kotlin/pluginterface/vst/ParameterChanges.kthttps://github.com/Durun/vst3kotlin/blob/f1082278b6c763fbebb4318c83f7aecdf501e233/vst3cwrapper/src/main/headers/cppinterface/memory.h#L16-L24 I have been using this as a reference for some of the lower-level KN stuff. This person defined:
Copy code
template<typename T>
T *allocArray(int length) {
    auto ptr = reinterpret_cast<T *>(malloc(sizeof(T) * length));
    if (ptr == nullptr) {
        fprintf(stderr, "Failed to allocate array of T (length=%d).\n", length);
        return nullptr;
    }
    return ptr;
}
And then uses it like you see in
ParameterChanges.kt
(or other places if you search for
allocArray
)
Disclaimer: I genuinely don't understand how some of the things in this repo work, but the person appears to know what they were doing
j
I think I cracked it
Copy code
internal inline operator fun <reified T : CVariable> CPointer<T>.set(index: Int, item: CValues<T>) {
  val offset = index * sizeOf<T>()
  item.place(interpretCPointer(rawValue + offset)!!)
}

internal inline fun <reified T : CVariable> NativePlacement.allocArrayOf(
  vararg items: CValues<T>,
): CArrayPointer<T> {
  val array = allocArray<T>(items.size)
  items.forEachIndexed { index, item ->
    array[index] = item
  }
  return array
}
👀 1
it's really the first part. the second is just convenience.
g
This is super useful -- thank you!