https://kotlinlang.org logo
k

katokay

06/20/2023, 6:05 PM
I am struggling with the correct native translation of this API in my kotlin-native code. http://www.lmdb.tech/doc/group__mdb.html#ga4fa8573d9236d54687c61827ebf8cac0 The code is currently looking like this, but I’ve tried a similar variation using alloc<MDB_val> without success. The error I get is invalid argument and I’m positive it’s the MDB_val argument(s). Any help would be appreciated. https://github.com/CoreyKaylor/kotlin-lmdb
Copy code
actual fun put(dbi: Dbi, key: ByteArray, data: ByteArray, vararg options: PutOption) {
        memScoped {
            key.usePinned { keyP ->
                val mdbKey = cValue<MDB_val>{
                    mv_data = keyP.addressOf(0)
                    mv_size = key.size.convert()
                }
                data.usePinned { dataP ->
                    val mdbData = cValue<MDB_val>{
                        mv_data = dataP.addressOf(0)
                        mv_size = data.size.convert()
                    }
                    println("Putting value")
                    check(mdb_put(ptr, dbi.dbi, mdbKey.ptr, mdbData.ptr, options.asIterable().toFlags()))
                    println("Put value")
                }
            }
        }
k

katokay

06/20/2023, 8:46 PM
I looked through and tried a similar approach again, however, I think the difference in your sample and mine is the string conversion to cstr, and my .addressOf(0). Feels like that is where it could be going wrong.
Pinning the ByteArray and using the address is similar to what was recommended here for NSData. https://youtrack.jetbrains.com/issue/KT-47482/Kotin-ByteArray-Objective-NSData-Interop-in-NSData.dataWithBytes
r

russhwolf

06/20/2023, 9:40 PM
Another thing to watch out for is using pointers past their lifetime. I'm a little suspicious of the
dbi
parameter in your snippet. If that came from a memscope that was already closed, it's probably referencing memory that isn't valid anymore.
k

katokay

06/21/2023, 12:54 PM
It’s possible, although the underlying type os UInt, the pointer is used inside memScoped to get the value. From that point forward the UInt should be reusable according to the docs and my experience with the dotnet library as well. Not saying you’re wrong, but it seemed unlikely to me. I’ll try a few things in this regard and report back.
Making progress. It was multiple items similar to what you suggested. It was giving me false confidence when other items I was using were passing several tests and I’m assuming it was a lucky race condition. Thanks for the help.
6 Views