Hey everyone, I need some help with C interop, her...
# kotlin-native
u
Hey everyone, I need some help with C interop, here is my problem: I want to use this function:
Copy code
int sodium_unpad(size_t *unpadded_buflen_p, const unsigned char *buf,
                 size_t padded_buflen, size_t blocksize);
Which looks like this in kotlin:
Copy code
@kotlinx.cinterop.internal.CCall public external fun sodium_unpad(unpadded_buflen_p: kotlinx.cinterop.CValuesRef<platform.posix.size_tVar /* = kotlinx.cinterop.ULongVarOf<kotlin.ULong> */>?, buf: kotlinx.cinterop.CValuesRef<kotlinx.cinterop.UByteVar /* = kotlinx.cinterop.UByteVarOf<kotlin.UByte> */>?, padded_buflen: platform.posix.size_t /* = kotlin.ULong */, blocksize: platform.posix.size_t /* = kotlin.ULong */): <http://kotlin.Int|kotlin.Int> { /* compiled code */ }
As you can see the first parameter is a pointer to
size_t
, I worked around this on 64 bit machines by doing this:
Copy code
var newSize = ULongArray(1) { 0UL }
    val newSizePinned = newSize.pin()
    sodium_unpad(
        newSizePinned.addressOf(0),
        paddedDataCopyPinned.toPtr(),
        paddedData.size.convert(),
        blocksize.convert()
    )
And it works fine on 64bit machines, unfortunately on 32bit machines it doesn't expect ULong, but UInt, and I get the following error:
Copy code
LibsodiumUtil.kt: (66, 13): Type mismatch: inferred type is CPointer<ULongVarOf<ULong>> but CValuesRef<size_tVar /* = UIntVarOf<UInt> */>? was expected
Any clues on how to move forward?
d
Quick fix is to use
UIntArray
instead.
u
Yeah, but wouldn't it then stop working on 64bit systems, I could split into 64/32bit sourcesets, but I'm trying to avoid that. I need something like
.convert()
but for arrays.
d
Don't use an array then, use a
size_tVar
.
u
Ok, I kinda worked around it, because in this specific case I know that the the
newSize
can never be larger than Int and it will never be more than one element, I went and casted it directly to array of size_t. It's absolutely awful, but at least it compiles and works properly in this particular case.
Copy code
newSizePinned.addressOf(0) as kotlinx.cinterop.CValuesRef<platform.posix.size_tVar>
I still think that it would be great if there is something like
.convert<size_t>()
mechanism but for arrays. But I'll try your suggestion about using size_tVar, that might be the best solution if it works in my case.