Kotlin/Native FAQ
最终更新: 2024/03/21
我要怎样运行我的程序?
你需要定义一个顶层的函数 fun main(args: Array<String>)
,
如果你不需要接受命令行参数, 也可以写成 fun main()
, 请注意不要把这个函数放在包内.
另外, 也可以使用编译器的 -entry
选项, 把任何一个函数指定为程序的入口点,
但这个函数应该接受 Array<String>
参数, 或者没有参数, 并且函数返回值类型应该是 Unit
.
Kotlin/Native 的内存管理机制是怎样的?
Kotlin/Native 使用一种自动化的内存管理机制, 与 Java 和 Swift 类似.
详情请参见 Kotlin/Native 内存管理器
我要怎样创建一个共享库?
可以使用编译器的 -produce dynamic
选项, 或在 Gradle 中使用 binaries.sharedLib()
.
kotlin {
iosArm64("mylib") {
binaries.sharedLib()
}
}
编译器会产生各平台专有的共享库文件
(对 Linux 环境 .so
文件, 对 macOS 环境是 .dylib
文件, 对 Windows 环境是 .dll
文件),
还会生成一个 C 语言头文件, 用来在 C/C++ 代码中访问你的 Kotlin/Native 程序中的所有 public API.
我要怎样创建静态库, 或 object 文件?
可以使用编译器的 -produce static
选项, 或在 Gradle 中使用 binaries.staticLib()
.
kotlin {
iosArm64("mylib") {
binaries.staticLib()
}
}
编译器会产生各平台专有的 object 文件(.a 库格式), 以及一个 C 语言头文件, 用来在 C/C++ 代码中访问你的 Kotlin/Native 程序中的所有 public API.
我要怎样在企业的网络代理服务器之后运行 Kotlin/Native?
由于 Kotlin/Native 需要下载各平台相关的工具链,
因此你需要对编译器或 gradlew
设置 -Dhttp.proxyHost=xxx -Dhttp.proxyPort=xxx
选项,
或者通过 JAVA_OPTS
环境变量来设置这个选项.
我要怎样为我的 Kotlin 框架指定自定义的 Objective-C 前缀?
可以使用编译器的 -module-name
选项, 或对应的 Gradle DSL 语句.
kotlin {
iosArm64("myapp") {
binaries.framework {
freeCompilerArgs += listOf("-module-name", "TheName")
}
}
}
kotlin {
iosArm64("myapp") {
binaries.framework {
freeCompilerArgs += ["-module-name", "TheName"]
}
}
}
我要怎样改变 iOS 框架的名称?
iOS 框架的默认名称是 <project name>.framework
.
要使用自定义的名称, 请使用 baseName
选项. 这个选项也会设置模块的名称.
kotlin {
iosArm64("myapp") {
binaries {
framework {
baseName = "TheName"
}
}
}
}
我要怎样对我的 Kotlin 框架启用 bitcode?
gradle plugin 默认会将 bitcode 添加到 iOS 编译目标中.
- 对于 debug 版, gradle plugin 会将 LLVM IR 数据占位器(placeholder)作为标记(marker)嵌入.
- 对于 release 版, gradle plugin 会将 bitcode 作为数据嵌入.
或者使用编译器参数: -Xembed-bitcode
(用于 release 版) 和 -Xembed-bitcode-marker
(用于 debug 版)
使用 Gradle DSL 的设置如下:
kotlin {
iosArm64("myapp") {
binaries {
framework {
// 使用 "marker" 嵌入 bitcode 标记 (用于 debug 版构建).
// 使用 "disable" 关闭嵌入.
embedBitcode("bitcode") // 用于 release 版构建.
}
}
}
}
这个选项的效果几乎等于 clang 的 -fembed-bitcode
/-fembed-bitcode-marker
和 swiftc 的 -embed-bitcode
/-embed-bitcode-marker
.
为什么我会遇到 InvalidMutabilityException
异常?
这个问题只会在旧的内存管理器中发生. 从 Kotlin 1.7.20 开始会默认启用新的内存管理器, 详情请参见 Kotlin/Native 内存管理.
这个异常发生很可能是因为, 你试图修改一个已冻结的对象值.
对象可以明确地转变为冻结状态, 对某个对象调用 kotlin.native.concurrent.freeze
函数,
那么只被这个对象访问的其他所有对象子图都会被冻结, 对象也可以隐含的冻结
(也就是, 它只被 enum
或全局单子对象访问 - 详情请参见下一个问题).
我要怎样让一个单子对象(Singleton Object)可以被修改?
这个问题只会在旧的内存管理器中发生. 从 Kotlin 1.7.20 开始会默认启用新的内存管理器, 详情请参见 Kotlin/Native 内存管理.
目前, 单子对象都是不可修改的(也就是, 创建后就被冻结), 而且我们认为让全局状态值不可变更, 通常是比较好的编程方式.
如果处于某些理由, 你需要在这样的对象内包含可变更的状态值, 请在对象上使用 @konan.ThreadLocal
注解.
另外, kotlin.native.concurrent.AtomicReference
类可以用来在被冻结的对象内,
保存指向不同的冻结对象的指针, 而且可以自动更新这些指针.
我要怎样使用还未发布的 Kotlin/Native 版本来编译我的项目?
首先, 请考虑使用 预览版.
如果你需要更新的开发版, 你可以通过源代码来编译 Kotlin/Native: clone Kotlin 代码仓库, 然后按照 这些步骤 进行编译.