Is there a way to add C definitions for a built-in...
# kotlin-native
n
Is there a way to add C definitions for a built-in C library (varies by Kotlin Native target) without having to do monkey patching (https://en.wikipedia.org/wiki/Monkey_patch)?
s
What exactly are you trying to achieve?
n
Extend a definition for a C symbol (eg a struct) without having to manually alter the source of the C library, which is automatically bundled for the target (eg Linux). Altering the library's source code would be messy since it would need to be done on every PC that runs the program, which isn't a good approach.
For instance there is a inotify_event Struct which is bare bones when looking at the mapping from a knm file:
Copy code
public final class inotify_event public constructor(rawPtr: kotlinx.cinterop.NativePtr /* = kotlin.native.internal.NativePtr */) : kotlinx.cinterop.CStructVar {
    public companion object : kotlinx.cinterop.CStructVar.Type {
    }
}
With this C example the inotify_event Struct has members which are missing from the mapping (mask, name etc): https://www.thegeekstuff.com/2010/04/inotify-c-program-example/
o
for me it has such fields:
Copy code
class inotify_event(rawPtr: NativePtr) : CStructVar(rawPtr) {
    
    companion object : Type(16, 4)
    
    var wd: __s32
        get() = memberAt<__s32Var>(0).value
        set(value) { memberAt<__s32Var>(0).value = value }
    
    var mask: __u32
        get() = memberAt<__u32Var>(4).value
        set(value) { memberAt<__u32Var>(4).value = value }
    
    var cookie: __u32
        get() = memberAt<__u32Var>(8).value
        set(value) { memberAt<__u32Var>(8).value = value }
    
    var len: __u32
        get() = memberAt<__u32Var>(12).value
        set(value) { memberAt<__u32Var>(12).value = value }
    
    val name: CArrayPointer<ByteVar>
        get() = arrayMemberAt(16)
}
n
Which Kotlin version is being used to generate that mapping? What host OS is being used? Currently using Kotlin 1.3.50 on Linux Mint 19.2. Are the mappings for the bundled C libraries already generated?
Looks like there is a bug with the cinterop tool. With Linux there are two versions of the inotify library. One is from the GCC C library ( https://sites.uclouvain.be/SystInfo/usr/include/sys/inotify.h.html ). The other one is from the Linux kernel library ( https://github.com/torvalds/linux/blob/master/include/uapi/linux/inotify.h ). Both versions are very similar. Even with the different library versions the cinterop tool should have picked up the inotify_event members from the header file.
o
Guess one declaration is opaque, and you’d better use another one from
platform.linux
.
m
Weird, but
class inotify_event
from
platform.linux
package shows fields on
android*
targets, and does not on
linux*
targets.
🤨 1
n
Interesting. So I'm not the only one noticing missing members with inotify_event in the mapping file on Linux targets.
Unfortunately there is no way to easily redefine a C symbol (eg inotify_event) in a def file for a Kotlin Native project ☹️ . Would be good to have a override system in cases where the mappings of a C library (especially bundled ones) turn to custard.
m
I think it's a bug in
cinterop
, probably related to
__flexarr
type of last field. So better just fix this bug.
👍 1