Hey all. So I'm a little confused about c strings ...
# kotlin-native
n
Hey all. So I'm a little confused about c strings in relation to struct members. If I have a c struct defined as such:
Copy code
typedef struct {
    const char *str;
} Example;
What is the intended way to store a string literal in
str
from Kotlin? Using
"String".cstr
doesn't work since
str
is a
CPointer<ByteVar>
, and
String.cstr
is a
CValues<ByteVar>
, and when I use
memScoped { ... }
with
getPointer(memScope)
, the CString is obviously freed as soon as the scope is finished, leaving me with an empty string in the struct member.
d
You need to copy the characters over in the
memScoped
block.
o
Use longer living placements, according to your string lifetime, like
foo.cstr.getPointer(nativeHeap)
, as documented in https://github.com/JetBrains/kotlin-native/blob/master/INTEROP.md#working-with-the-strings
n
@Dico Copying the characters over doesn't work since the struct only has room for a pointer to the char array. In C, this isn't a problem since string literals are allocated in shared read-only memory, but this doesn't work in kotlin.
@olonho
foo.cstr.getPointer(nativeHeap)
doesn't work since
getPointer(...)
expects an
AutoFreeScope
, and nativeHeap is only a
NativeFreeablePlacement
. Same with
placeTo
. This is with kotlin 1.3.21. The docs seem to be a bit out of date.
d
Allocate memory in nativeHeap, copy the characters, set the ptr?
n
Oh, yeah, that works. But as per the docs, as olonho mentioned, that didn't seem like the intended solution. But it looks like for now it's the only one?
o
Indeed docs somewhat outdated, better use smth like
Copy code
val a = Arena()
val ptr = "Hello".cstr.getPointer(a)
//  a.clear() when pointer no longer needed
n
That works perfectly, thanks for the help!