Найти в Дзене
Один Rust не п...Rust

Rust & KMM

Для чего нужна данная статья? :
- Изучить интеграцию Kotlin Multiplatform с Rust через FFI.
- Написать правильный код.

Зачем Вам это уметь? :

Научиться работать с разными моделями памяти Rust и Kotlin, и научиться передавать данные между Rust и Kotlin.

Создайте новый проект Kotlin Multiplatform в среде разработки, поддерживающей KMM. Создайте файл с общим кодом, например, CommonCode.kt, содержащий бизнес-логику:

expect class RustIntegration() {
fun rustFunction(): String
}

Теперь создайте файл с реализацией для Android и iOS commonMain/src/commonMain/kotlin/CommonCode.kt:

class RustIntegration {
actual fun rustFunction(): String {
return "Kotlin says: ${PlatformSpecific().platformFunction()}"
}
}

Создайте файл lib.rs для библиотеки Rust:

#[no_mangle]
pub extern "C" fn rust_function() -> *const i8 {
"Hello from Rust\0".as_ptr() as *const i8
}

Затем создайте Cargo.toml:

[package]
name = "rust_integration"
version = "0.1.0"
edition = "2021"
[lib]
crate-type = ["cdylib"]
[dependencies]

Выполните сборку библиотеки Rust, используя cargo build.

Создайте директорию native в commonMain и поместите в нее файл RustIntegration.kt (commonMain/src/commonMain/kotlin/native/RustIntegration.kt):

import kotlinx.cinterop.CPointer
import kotlinx.cinterop.alloc
import kotlinx.cinterop.toKString
import platform.posix.free
import platform.posix.strcpy
import platform.posix.free
import platform.posix.malloc

actual class RustIntegration {
actual fun rustFunction(): String {
return rustFunctionFromC()
}

private external fun rustFunctionFromC(): String
}

Создайте директории androidMain и iosMain и поместите в них пустые файлы RustIntegration.kt(androidMain/src/androidMain/kotlin/native/RustIntegration.kt):

actual class RustIntegration {
actual fun rustFunction(): String {
return "Android implementation"
}
}

(iosMain/src/iosMain/kotlin/native/RustIntegration.kt):

actual class RustIntegration {
actual fun rustFunction(): String {
return "iOS implementation"
}
}

Создайте файл rust_integration.h в директории iosMain/cpp/:

(iosMain/cpp/rust_integration.h):

const char* rust_function();

Создайте файл rust_integration.cpp в директории iosMain/cpp/:

(iosMain/cpp/rust_integration.cpp):

#include "rust_integration.h"
extern "C" const char* rust_function() {
return rust_function();
}

В файле build.gradle.kts для iOS (iosApp или iosFramework) добавьте следующий блок:

kotlin {
ios {
binaries {
framework("MyFramework") {
freeCompilerArgs += "-Xcc -I${projectDir}/src/iosMain/cpp"
}
}
}
}

В мобильном приложении (Android или iOS) используйте созданный код:

val rustIntegration = RustIntegration()
println(rustIntegration.rustFunction())