我正在try 构建一个Kotlin/Native库,并在Android应用程序中使用它.我实际上希望使用预构建的共享库,而不是.jar,因为我希望我的代码被混淆.
我已经设法让我的Kotlin/Native库在我的Android应用程序中使用JNI和许多试验和错误.问题是,我只使用这个Kotlin/Native代码创建了一个非常简单的"Hello world"函数:
fun sayHello(): String {
return "Hello, Kotlin/Native!"
}
以下是JNI的C++代码:
extern "C" JNIEXPORT jstring JNICALL
Java_com_my_package_NativeLib_sayHello(
JNIEnv *env,
jobject /* this */) {
libshared_lib_ExportedSymbols *lib = libshared_lib_symbols();
return env->NewStringUTF(lib->kotlin.root.sayHello());
}
最后是我的Android类中的这段Kotlin代码:
class NativeLib {
external fun sayHello(): String
companion object {
init {
System.loadLibrary("native-lib")
}
}
}
郑重声明,我正在将带有Gradle的Kotlin/Native构建为Android Target的预置共享库.然后我将.so
文件复制/粘贴到我的应用程序的libs文件夹中,然后使用一些Gradle魔术让它正常工作.
然而,当我开始编写一个函数时,它变得更复杂了,该函数使用一个字节数组作为参数,如下所示(实现与此无关):
fun readByteArray(byteArray: ByteArray): String {
val unsignedByteArray = byteArray.toUByteArray()
var i = 0
while (i < byteArray.size) {
// Access the array
val byte = unsignedByteArray[i].toUInt()
}
return "Done reading the array"
}
然后将这个添加到我在Android端的NativeLib
个类中:
external fun readByteArray(byteArray: ByteArray): String
JNI C++的类似功能应该是什么:
extern "C" JNIEXPORT jstring JNICALL
Java_com_my_package_NativeLib_readByteArray(JNIEnv *env, jobject,
jbyteArray byte_array) {
libshared_lib_ExportedSymbols *lib = libshared_lib_symbols();
// What to do here?
return env->NewStringUTF(lib->kotlin.root.readByteArray(/* and here? */));
}
问题是Kotlin/Native正在生成这个头文件:
typedef void* libshared_lib_KNativePtr;
...
typedef struct {
libshared_lib_KNativePtr pinned;
} libshared_lib_kref_kotlin_Byte;
...
typedef struct {
libshared_lib_KNativePtr pinned;
} libshared_lib_kref_kotlin_ByteArray;
...
struct {
struct {
const char* (*readByteArray)(libshared_lib_kref_kotlin_ByteArray byteArray);
const char* (*sayHello)();
} root;
} kotlin;
...
这就是我被困住的地方,我到底应该如何制造一个libshared_lib_kref_kotlin_ByteArray
?以下是我到目前为止所try 的方法,但在代码试图读取数组时发生崩溃:
extern "C" JNIEXPORT jstring JNICALL
Java_com_my_package_NativeLib_readByteArray(JNIEnv *env, jobject,
jbyteArray byte_array) {
libshared_lib_ExportedSymbols *lib = libshared_lib_symbols();
libshared_lib_KNativePtr ptr = env->GetDirectBufferAddress(byte_array);
libshared_lib_kref_kotlin_ByteArray byteArray;
byteArray.pinned = ptr;
return env->NewStringUTF(lib->kotlin.root.readByteArray(byteArray));
}
我也试过使用GetByteArrayElements()
,但没有成功.
有人知道如何处理那些Kotlin生成的类型吗?