记录一下Kotlin CInterop的使用

AI智能摘要
作者因Kotlin Native标准库缺少文件修改时间API,转而通过C语言编写函数并成功集成。文章记录了使用Kotlin CInterop的关键步骤:需用绝对路径定义头文件和静态库路径,在def文件中配置headers、package及staticLibraries参数;同时需在build.gradle.kts中指定目标平台并配置cinterops。最后建议通过expect/actual机制实现多平台适配,生成klib文件后即可调用C函数绑定。
— AI 生成的文章内容摘要

开始

因为Kotlin native的标准库还不是很完善和成熟,所有有很多东西都得依靠外部例如调用C函数、库等,我就碰到了这个问题, 我现在写了一个Maven仓库服务器用到了Native但是官方的IO API和posixAPI都没有获取文件或者文件夹上次修改时间的API, 所以我就只能转向使用C写个简单的函数来让Kotlin使用于是在尝试+查资料2个小时之后终于成功了,下面是一些小记录

Def文件定义

def文件到目前(2025年4月19日)为止并没有代码提示和补全,所以全靠记忆和资料。
先看一下头文件的写法

headers = E:\\projects\\KMVNRepo\\backend\\src\\cinterop\\include\\file_time.h

有一个坑点就是这个头文件必须是绝对路径不能是相对路径, 这点卡了我好久我才发觉hh

然后就是如果要使用c语言或者其它语言编译出来的静态库.a文件的话得主动写上去这个.a文件的名字和这个库的路径, 这个路径也得是绝对路径

就像下面这样

staticLibraries = libfiletime-linuxx64.a
libraryPaths = E:\\projects\\KMVNRepo\\backend\\src\\cinterop\\libs

下面是一个完整的def文件示例

headers = E:\\projects\\KMVNRepo\\backend\\src\\cinterop\\include\\file_time.h
package = cn.rtast.kmvnrepo.time
staticLibraries = libfiletime-linuxx64.a
libraryPaths = E:\\projects\\KMVNRepo\\backend\\src\\cinterop\\libs

然后在build.gradle.kts里面指定需要为哪个平台创建binding(也就是自动生成.knm, .knm就是.klib文件内的一个结构文件这个文件里面只有结构并没有具体实现, 具体实现都放到klib内的二进制文件内了, 这个文件就是用来IDE自动补全提示用的)

kotlin {
    linuxX64 {
        compilations["main"].cinterops {
            val fileTimeLinux by creating {
                definitionFile = project.layout.projectDirectory.dir("src/cinterop/file_time_linuxx64.def").asFile
                compilerOpts("-Isrc/cinterop/")
            }
        }
    }
    mingwX64 {
        compilations["main"].cinterops {
            val fileTimeMingw by creating {
                definitionFile = project.layout.projectDirectory.dir("src/cinterop/file_time_mingwx64.def").asFile
                compilerOpts("-Isrc/cinterop/")
                // 这里的src/cinterop就是def文件放的位置
            }
        }
    }
}

最后在IDEA里面sync一下就可以发现build/libs/里面有自动生成的klib文件了然后就可以使用自动生成的C函数binding了

再提一嘴: 最好在commonMain创建一个expect函数然后在每个target actual这个函数这样才能使用各自平台的C binding

温馨提示:

1.本站大部分内容均收集于网络!若内容若侵犯到您的权益,请发送邮件至:xiaoman1221@yhdzz.cn,工作室将第一时间处理!

2.资源所需价格并非资源售卖价格,是收集、整理、编辑详情以及本站运营的适当补贴,并且本站不提供任何免费技术支持。

3.所有资源仅限于参考和学习,版权归原作者所有。

Kotlin学习默认

记录一下在Kotlin Native上嵌入资源的插件开发过程

2025-4-16 22:00:57

好软推荐

更好地使用Notion

2024-9-25 21:17:23

22 条回复 A文章作者 M管理员
  1. 光尘拾荒

    这个方案在macOS ARM64上跑过吗?担心lib兼容性问题。

  2. 泡澡小鸭子

    前几天刚搞完类似的东西,用stat函数取时间戳,折腾好久才通。

  3. 麒麟

    哎,又是被Kotlin Native生态劝退的一天,慢慢填坑吧。

  4. 一只小鸟

    蹲个后续,有没有性能对比数据啊?想看看C层调用损耗大不大。

  5. 搞笑薯片

    官方IO缺功能太离谱了,连个基础file time都要自己搞C层。

  6. 彩虹屁星人

    klib位置能不能改好像得在gradle里配置output per compilation,没试过但理论上可行。

  7. 之前搞K/N调SQLite也是这样,最后靠Cinterop硬扛过来的。

  8. 会讲笑话的玉米

    楼主用的是Windows吧?Linux下路径写法不太一样,容易出问题。

  9. NatsuBeam

    这绝对路径的坑简直了,搞了我一下午才找到原因。

  10. 幻烬旅

    hhh又被Cinterop折磨的一天,深有同感

  11. 睡不醒的喵

    感觉官方应该把基础IO功能补全的

  12. 风水韵

    expect/actual这招好用,跨平台必备

    • 鬼语梦

      expect/actual真是跨平台救星,不然真要手动写一堆平台判断。

    • RTAkland

      def文件要是再不加补全,迟早有人写出IDE插件来救命hhh

  13. 茶语心香

    同步之后klib生成的位置能自定义吗?

  14. 盐商黄

    kotlin native的生态确实还需要时间完善🤔

  15. 瑶琴怨

    为啥不用相对路径呢?绝对路径移植起来很麻烦啊

  16. 之前写FFI也遇到过类似问题,最后用CMake解决了

  17. 独赏夜月

    def文件没代码补全确实头疼,每次都得查文档

  18. 雨师伞

    想问下M1芯片能用这个方案吗?

    • RTAkland

      M1应该能用,不过得确认下C库有没有arm64版本,交叉编译可能得调一堆参数。

  19. 务实稳重

    这个绝对路径的坑我也踩过,卡了半天才发现

个人中心
购物车
优惠劵
今日签到
有新私信 私信列表
搜索