kin*_*ton 8 c++ android kotlin kotlin-native kotlin-multiplatform
我第一次使用 Android Studio 构建多平台项目。我创建了一个 Android 应用程序模块,该模块使用 Android 上的多平台库。我还使用 XCode 构建了一个 iOS 应用程序,该应用程序使用 iOS 上的多平台库。一切工作正常,我能够使用由不同的Android 和 iOSexpect fun实现的。actual fun
我还用 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
Run Code Online (Sandbox Code Playgroud)
我使用 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
Run Code Online (Sandbox Code Playgroud)
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
Run Code Online (Sandbox Code Playgroud)
如何cinterop在我的 kotlin-multiplatform 项目中使用创建的库?
我找到了不同的导入方法,但没有找到有关如何导入的完整描述。 他们说我可以使用类似的东西:
implementation files("ping.klib")
Run Code Online (Sandbox Code Playgroud)
我为 iOS 项目做到了这一点,但我仍然不知道如何在 Android 和 iOS 上访问 kotlin 类。
这是我的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
Run Code Online (Sandbox Code Playgroud)
编辑
我改变了问题,因为最初,我认为这cinterop不是创建 klib 库,但这只是一个错误:我正在文件ping-build夹中查找,但文件位于该文件夹之外。这样我就解决了一半的问题。
EDIT2
我添加了build.script
我很高兴看到 KLIB 一切都很好,现在是关于图书馆的使用。
首先,我必须提到这个库只能由 Kotlin/Native 编译器使用,这意味着它将可用于某些目标(请参阅此处的列表)。然后,如果您要将 C 库的使用包含到 MPP 项目中,那么最好通过 Gradle 脚本生成绑定。它可以在目标内部完成,例如请参阅此文档。对于你的 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")
}
}
}
}
Run Code Online (Sandbox Code Playgroud)
此代码片段会将 cinterop 任务添加到您的 Gradle,并提供模块以包含import c.ping.*在相应的 Kotlin 文件中。
| 归档时间: |
|
| 查看次数: |
3296 次 |
| 最近记录: |