Hey everybody, is there a way to pass a nullable p...
# kotlin-native
j
Hey everybody, is there a way to pass a nullable primitive pointer to a Kotlin function? Context: I'm trying to pass a Kotlin function to a C library as a callback and it needs to accept a nullable primitive pointer as an argument. More info in thread.
For non-null primitives, the solutions is straight forward:
Copy code
fun setInt(pointer: CPointer<IntVar>) {
    pointer.pointed.value = 5
}
This can be consumed from C:
Copy code
libnative_KInt x;
libnative_symbols()->kotlin.root.setInt(&x);
// x == 5
For nullable primitives, I can't seem to find anything that works. I've tried the following:
Copy code
fun setNullableInt(pointer: CPointer<COpaquePointerVar>) {
    pointer.pointed.value = StableRef.create(5).asCPointer()
}
Calling the above from C like so:
Copy code
libnative_kref_kotlin_Int x;
libnative_symbols()->kotlin.root.setNullableInt(&x);
// Consume x
libnative_symbols()->DisposeStablePointer(x.pinned);
But this results in x being populated with a seemingly random value.
n
What is the signature of the C function from the Kotlin side?
Note that primitive data types cannot be null since they are passed by value, although C Pointers can still be null.
Not a good idea for the C program to interact with the Kotlin Native runtime (via private APIs), and the Kotlin Native memory model (GC), which is asking for trouble.
j
Ok, here is a more fleshed out example: I have a function from an existing C library that looks something like this:
Copy code
void allocate(void* into, void (*allocator)(void*))
This function contains general purpose allocation logic and ultimately delegates the allocation to the provided
allocator
function by invoking
allocator(into)
. The
allocator
function is responsible for instantiating/initializing the value pointed to by
into
. For primitives this works well. Considering the
setInt
method above, I could do the following to initialize a KInt from C:
Copy code
libnative_KInt x;
allocate(&x, libnative_symbols()->kotlin.root.setInt);
// x has successfully been set to 5
However, when dealing with Kotlin objects this becomes much more tricky. For example, consider a nullable KInt which is exposed like so in the C API of my Kotlin library:
Copy code
typedef struct {
  libnative_KNativePtr pinned;
} libnative_kref_kotlin_Int;
I can easily write an
allocator
function for this nullable KInt from C by utilizing the builtin
createNullableInt
function like so:
Copy code
void setNullableInt(libnative_kref_kotlin_Int* pointer) {
    *pointer = libnative_symbols()->createNullableInt(5);
}

void main() {
    // This works fine
    libnative_kref_kotlin_Int x;
    allocate(&x, setNullableInt);
    // x is now a nullable Int with value 5
    // Finally, dispose of the object
    libnative_symbols()->DisposeStablePointer(x.pinned);
}
But, what I really want is for the
setNullableInt
function to be implemented in Kotlin and have a signature identical to the above
setNullableInt
function implemented in C. I suppose my question is: 1. Is it possible to translate the above
setNullableInt
from C to Kotlin? 2. And, if so, what does the implementation of such a Kotlin function look like? Appreciate the help.