https://kotlinlang.org logo
#kotlin-native
Title
# kotlin-native
p

Patrick

12/18/2020, 1:27 PM
Is there a way to provide a ByteArray as a parameter to a C-interop function that expects
const char*
? I've read the documentation but couldn't figure out how to do it. Adding
noStringConversion = xxx
doesn't seem to do anything for me. I don't want to convert to a String before passing the value, I just want to pass the ByteArray as is.
k

Kuba Petržílka

12/18/2020, 2:12 PM
byteArray.toCValues().ptr
?
p

Patrick

12/18/2020, 2:13 PM
Unresolved reference. None of the following candidates is applicable because of receiver type mismatch: public val <T : CPointed> ???.ptr: CPointer<???> defined in kotlinx.cinterop
k

Kuba Petržílka

12/18/2020, 2:15 PM
you have to do it within memScoped { }
another option is probably to use
byteArray.refTo(0)
but I haven't tried that one
p

Patrick

12/18/2020, 2:17 PM
Type inference failed. Expected type mismatch: inferred type is CPointer<ByteVar /* = ByteVarOf<Byte> */> but String? was expected
k

Kuba Petržílka

12/18/2020, 2:19 PM
can you post the whole block of code?
p

Patrick

12/18/2020, 2:19 PM
Copy code
actual suspend fun sendData(nScannerId: Int, pDataBuf: ByteArray): Int {
    return executeInWorker(blueWorker, SendData(nScannerId, pDataBuf)) { data ->
        memScoped {
            nim_SendData(data.scannerId, data.data.toCValues().ptr, data.data.size)
        }
    }
}
It's executed on a worker thread, don't know if it has anything to do with it
Copy code
data class SendData(val scannerId: Int, val data: ByteArray)
k

Kuba Petržílka

12/18/2020, 2:21 PM
what about
executeInWorker
?
k

Kuba Petržílka

12/18/2020, 2:24 PM
ok and
nim_SendData
?
p

Patrick

12/18/2020, 2:24 PM
Copy code
DLL_EXP int    nim_SendData         ( int nScannerID, const char *pDataBuf, int nLen );
This is the C interop function
const char* means Kotlin wants a String, but I don't want to convert my bytearray to a string before calling the function, because the encoding should not mess it up.
k

Kuba Petržílka

12/18/2020, 2:25 PM
and how does the generated interop signature look like?
p

Patrick

12/18/2020, 2:25 PM
Where can I see this?
k

Kuba Petržílka

12/18/2020, 2:25 PM
if you just control+click it in the IDE ?
but nevermind, it wants string, so you have to pass a string
p

Patrick

12/18/2020, 2:26 PM
But I don't want to 😞
And according to the documentation it should work, right? I have no idea, the Native documentation is not really intuitive
Apparently there is no other way than to encode it as a string with UTF-8, but I don't want to do that, because the byteArray might not be UTF-8 encoded
k

Kuba Petržílka

12/18/2020, 2:35 PM
yes, I agree on that.. but it is strange because if you have a C function that is expecting
char *
than I would expect the generated kotlin knm with a
CValuesRef<ByteVar>
signature.. like in the example in the doc:
Copy code
void pass_string(char* str) {
}
becomes:
Copy code
fun pass_string(str: CValuesRef<ByteVar /* = ByteVarOf<Byte> */>?)
p

Patrick

12/18/2020, 2:42 PM
I think
char *
is different from
const char*
According to this it should work, but it doesn't currently, so I don't know
k

Kuba Petržílka

12/18/2020, 2:47 PM
hm , you might be right, I was about to say you will have to call either:
Copy code
toKString()
or
Copy code
toKStringFromUtf8()
p

Patrick

12/18/2020, 2:48 PM
Yep, but I don't want to do that
If I do this, it works, but then my bytearray is utf-8 encoded, which I don't like
k

Kuba Petržílka

12/18/2020, 2:51 PM
Ok, I see your point now.. so you say the
noStringConversion =
is not working?
did you regenerate the interop bindings after changing this?
p

Patrick

12/18/2020, 3:02 PM
Yes, I did
I deleted the whole build folder and tried again, but still same issue
Or do I have to do something like
byteArray.ptr
?
k

Kuba Petržílka

12/18/2020, 4:33 PM
You should be able to see which type it is expecting. Do you see the generated stubs?
a

Animesh Sahu

12/20/2020, 7:49 AM
You can just simply write
"your string".cstr
p

Patrick

12/21/2020, 10:26 AM
@Animesh Sahu How does that help me? I don't have a string in the first place. And decoding it to string might loose information, depending on the encoding.
a

Animesh Sahu

12/21/2020, 3:30 PM
🤔 If that's the case cValuesOf seems to be the last option if I am right...
7 Views