Впервые я использую Android Studio для создания мультиплатформенного проекта. Я создал Android модуль приложения, который использует многоплатформенную библиотеку на Android. Я также использовал XCode для создания приложения iOS, которое использует многоплатформенную библиотеку на iOS. Все отлично работает, и я могу использовать expect fun
, который реализован различными actual fun
для Android и iOS.
Я также создал библиотеку на C ++, которая предоставляет C interface.
#ifndef PINGLIB_LIBRARY_H
#define PINGLIB_LIBRARY_H
#ifdef __cplusplus
extern "C" {
#endif
typedef struct {
long long elapsed;
} PingInfo;
typedef void (*PingCallback)(PingInfo pingInfo);
typedef struct
{
PingCallback pingUpdate;
} PingObserver;
void* ping(const char * url, const PingCallback *pingCallback);
void subscribe(void* pingOperation);
void unsubscribe(void* pingOperation);
#ifdef __cplusplus
}
#endif
#endif //PINGLIB_LIBRARY_H
Я использую CLion для сборки кода C ++. Я создал файл .def
, который я использую для построения библиотеки, используя cinterop
.
package = com.exercise.pinglib
headers = PingLibrary.h
linkerOpts.linux = -L/usr/lib/x86_64-linux-gnu
compilerOpts = -std=c99 -I/Users/username/myproject/ping/ping/header
staticLibraries = libping.a
libraryPaths = /opt/local/lib /Users/username/myproject/ping/cmake-build-debug
libping.a
- библиотека, созданная для построения кода C ++. Он создается в папке /Users/username/myproject/ping/cmake-build-debug
Когда я запускаю команду cinterop -def ping.def -o ping
, он создает файл klib и папку, содержащую файл manifest.properties
, подпапку natives
, содержащую файл cstubs.bc
и подпапка kotlin
с файлом .kt
.
ping.klib
-ping-build
manifest.properties
-natives
cstubs.bc
-kotlin
-com
-exercise
-pinglib
pinglib.kt
Как я могу использовать библиотеку, созданную cinterop
в моем kotlin -мультиплатформенном проекте?
Я нашел разные способы его импорта, но я не нашел полного описания того, как это сделать. Здесь говорят, что я могу использовать что-то вроде:
implementation files("ping.klib")
Я сделал это для проекта iOS, но я до сих пор не знаю, как получить доступ к классам kotlin. на Android ни на iOS.
Это мой build.gradle
apply plugin: 'com.android.library'
apply plugin: 'kotlin-multiplatform'
android {
compileSdkVersion 28
defaultConfig {
minSdkVersion 15
}
buildTypes {
release {
minifyEnabled true
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
}
}
}
kotlin {
targets {
final def iOSTarget = System.getenv('SDK_NAME')?.startsWith('iphoneos') ? presets.iosArm64 : presets.iosX64
fromPreset(iOSTarget, 'ios') {
binaries {
framework('shared')
}
}
fromPreset(presets.android, 'android')
}
sourceSets {
// for common code
commonMain.dependencies {
api 'org.jetbrains.kotlin:kotlin-stdlib-common'
}
androidMain.dependencies {
api 'org.jetbrains.kotlin:kotlin-stdlib'
}
iosMain.dependencies {
implementation files("ping.klib")
}
}
}
configurations {
compileClasspath
}
task packForXCode(type: Sync) {
final File frameworkDir = new File(buildDir, "xcode-frameworks")
final String mode = project.findProperty("XCODE_CONFIGURATION")?.toUpperCase() ?: 'DEBUG'
final def framework = kotlin.targets.ios.binaries.getFramework("shared", mode)
inputs.property "mode", mode
dependsOn framework.linkTask
from { framework.outputFile.parentFile }
into frameworkDir
doLast {
new File(frameworkDir, 'gradlew').with {
text = "#!/bin/bash\nexport 'JAVA_HOME=${System.getProperty("java.home")}'\ncd '${rootProject.rootDir}'\n./gradlew \$@\n"
setExecutable(true)
}
}
}
tasks.build.dependsOn packForXCode
РЕДАКТИРОВАТЬ Я изменил вопрос, потому что изначально я думал, что cinterop
не создавал библиотеку klib, но это была просто ошибка: я искал в папке ping-build
, но файл находится вне этой папки. Таким образом, я решил половину вопроса.
EDIT2 Я добавил build.script