我第一次使用Android Studio构建一个多平台项目。我创建了一个Android应用程序模块,该模块在Android上使用多平台库。
我还使用XCode构建了一个在iOS上使用多平台库的iOS应用。
一切正常,我可以使用由不同expect fun
实施的actual fun
来安装Android和iOS。
我还用C ++创建了一个暴露C接口的库。
#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
文件和一个{{1 }}子文件夹和一个kotlin
文件。
.kt
如何在我的kotlin-multiplatform项目中使用ping.klib
-ping-build
manifest.properties
-natives
cstubs.bc
-kotlin
-com
-exercise
-pinglib
pinglib.kt
创建的库?
我找到了导入它的不同方法,但是我没有找到关于它的完整描述。 Here他们说我可以使用类似的东西:
cinterop
我在iOS项目中做到了这一点,但我仍然不知道如何在Android和iOS上都不访问kotlin类。
这是我的 implementation files("ping.klib")
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
并不是在创建klib库,但这只是一个错误:我在cinterop
文件夹中查找,但是文件不在该文件夹中。所以我解决了一半的问题。
EDIT2
我添加了ping-build
答案 0 :(得分:1)
我很高兴看到KLIB一切正常,现在有关库的使用。
首先,我要提到的是,该库只能由Kotlin / Native编译器使用,这意味着它将可用于某些目标(请参见列表here)。然后,如果要将C库的使用包含到MPP项目中,最好通过Gradle脚本生成绑定。它可以在目标内部完成,例如,请参见this文档。对于您的iOS目标,它应该像这样:
kotlin {
iosX64 { // Replace with a target you need.
compilations.getByName("main") {
val ping by cinterops.creating {
defFile(project.file("ping.def"))
packageName("c.ping")
}
}
}
}
此代码段会将cinterop任务添加到您的Gradle中,并提供将import c.ping.*
之类的模块包含在相应Kotlin文件中的功能。