I have a C function that takes in the following: ...
# kotlin-native
k
I have a C function that takes in the following:
Copy code
int TextCopy(char *dst, const char *src);
dst
would be an array of char in C I believe. K/N wants a
CValuesRef<ByteVar>
What's the best way to pass that through? I was thinking of
ByteArray.toCValues()
but something tells me no..
j
What's your goal when calling this function? Where is
src
coming from and what do you need to do with
dst
? Mostly it depends if you need to hang on to a reference to
dst
long term, or if its usage is within a specific scope, how you want to allocate its memory.
k
we copy one string to another and return bytes copied
overall the goal is to simply wrap around the C function from the interop to a Kotlin function
j
Is your goal to return a Kotlin
String
, a
CharArray
, a
CPointer<u_charVar>
, something else?
In general you can do something like this:
Copy code
memScoped {
    val dst: CPointer<u_charVar> = allocArray(length)
    val result = TextCopy(dst, src)
}
But
dst
will only be allocated until the end of the
memScoped
block. This is why I asked what ultimately you need to do with
dst
. If you turn it into a Kotlin object (
String
or
CharArray
), it will then be managed by the Kotlin GC. But as long as it's a C variable you allocated, you need to manage the memory manually.
k
I'm most certain it would return a String actually. I think what the C lib has tried to do with TextCopy is wrapping strcpy around it for some reason
j
it would return a String actually
Do you mean a Kotlin
String
object? Why is it you need to copy the string with this C function? What is the
src
input string? Is there a reason you wouldn't just copy it to a Kotlin
String
directly?
👍 1
k
It's more of a learning curve. Learning many other ways of wrapping around C Interop, and thank you for the help!
j
This makes more sense if it's just to learn Kotlin C interop. The various ways to allocate native memory are discussed here. If your usage isn't scoped for automatically freeing with
memScoped { ... }
, you can allocate with
nativeHeap
, but you need to manually free the memory when you're done with it. As for working with strings, you can normally call
toKString()
on a native C string pointer to convert to a Kotlin
String
.
k
Yeah I found that toKString solves all my problems with C strings. One out of curiosity question... Let's say there is a C function that requires to take in a char *my_text and modifies that variable and requires it to be free after calling the said function. How would this work in K/N? Will the GC take care of it? Or best to wrap it around in memScoped?
j
If you're passing a
char *
pointer to a C function from Kotlin, you have to allocate that memory natively somehow, in one of the ways described in the link above. GC won't automatically clean up natively allocated memory. It will depend on your use case whether that memory can be scoped with
memScoped
because you only need it in a scope directly at the call site to the C function or if you intend to keep the native memory around for longer, in which case, you'd allocate with
nativeHeap
and need to take care of calling free on it when you're done with it.
👍 1