diff --git a/jni-utils/src/commonMain/kotlin/io/github/landrynorris/jniutils/JClass.kt b/jni-utils/src/commonMain/kotlin/io/github/landrynorris/jniutils/JClass.kt index 85f95f4..1b01888 100644 --- a/jni-utils/src/commonMain/kotlin/io/github/landrynorris/jniutils/JClass.kt +++ b/jni-utils/src/commonMain/kotlin/io/github/landrynorris/jniutils/JClass.kt @@ -18,6 +18,7 @@ val Float = JClass("F") val Double = JClass("D") val Void = JClass("V") val String = createSignature("java.lang.String") +val Object = createSignature("java.lang.Object") val BooleanArray = JClass("[Z") val ByteArray = JClass("[B") diff --git a/jni-utils/src/commonMain/kotlin/io/github/landrynorris/jniutils/Signature.kt b/jni-utils/src/commonMain/kotlin/io/github/landrynorris/jniutils/Signature.kt index 5ccfe18..ebfcf2b 100644 --- a/jni-utils/src/commonMain/kotlin/io/github/landrynorris/jniutils/Signature.kt +++ b/jni-utils/src/commonMain/kotlin/io/github/landrynorris/jniutils/Signature.kt @@ -1,5 +1,6 @@ package io.github.landrynorris.jniutils +import kotlinx.cinterop.CPointed import platform.android.jobject import platform.android.jstring import kotlin.reflect.KClass @@ -12,7 +13,11 @@ data class Signature(val parameterClasses: List, val returnClass: JClass } } -inline fun signature() = classToSignature(typeOf()) +inline fun signature() = if(T::class == CPointed::class) { + error("We can't get the type from a CPointed yet.") +} else { + classToSignature(typeOf()) +} inline fun classToSignature(type: KType) = when(type) { typeOf() -> Void @@ -25,13 +30,14 @@ inline fun classToSignature(type: KType) = when(type) { typeOf() -> Float typeOf() -> Double typeOf() -> BooleanArray + typeOf() -> LongArray typeOf() -> ByteArray typeOf() -> ShortArray typeOf() -> CharArray typeOf() -> IntArray typeOf() -> FloatArray typeOf() -> DoubleArray - typeOf() -> createSignature("java.lang.Object") + typeOf() -> Object typeOf() -> String else -> createSignature(type.toString()) } diff --git a/jni-utils/src/commonMain/kotlin/io/github/landrynorris/jniutils/SignatureFromFunction.kt b/jni-utils/src/commonMain/kotlin/io/github/landrynorris/jniutils/SignatureFromFunction.kt index 9c626f3..435e15c 100644 --- a/jni-utils/src/commonMain/kotlin/io/github/landrynorris/jniutils/SignatureFromFunction.kt +++ b/jni-utils/src/commonMain/kotlin/io/github/landrynorris/jniutils/SignatureFromFunction.kt @@ -1,28 +1,35 @@ package io.github.landrynorris.jniutils import kotlinx.cinterop.CPointer -import kotlinx.cinterop.staticCFunction import platform.android.JNIEnvVar import platform.android.jobject import kotlin.reflect.typeOf inline fun signature(function: (CPointer, jobject) -> R): String { + if(R::class.isCPointer()) error("CPointer classes are not currently supported") return Signature(listOf(), classToSignature(typeOf())).toString() } inline fun signature(function: (CPointer, jobject, T) -> R): String { + if(T::class.isCPointer() || R::class.isCPointer()) + error("CPointer classes are not currently supported") return Signature(listOf(classToSignature(typeOf())), classToSignature(typeOf())).toString() } inline fun signature(function: (CPointer, jobject, T, S) -> R): String { + if(T::class.isCPointer() || R::class.isCPointer() || S::class.isCPointer()) + error("CPointer classes are not currently supported") return Signature(listOf(typeOf(), typeOf()).map { classToSignature(it) }, classToSignature(typeOf())).toString() } inline fun signature(function: (CPointer, jobject, T, S, U) -> R): String { + if(T::class.isCPointer() || R::class.isCPointer() || S::class.isCPointer() + || U::class.isCPointer()) + error("CPointer classes are not currently supported") return Signature(listOf(typeOf(), typeOf(), typeOf()).map { classToSignature(it) }, classToSignature(typeOf()) ).toString() @@ -30,6 +37,9 @@ inline fun inline fun signature(function: (CPointer, jobject, T, S, U, V) -> R): String { + if(T::class.isCPointer() || R::class.isCPointer() || S::class.isCPointer() + || U::class.isCPointer() || V::class.isCPointer()) + error("CPointer classes are not currently supported") return Signature(listOf(typeOf(), typeOf(), typeOf(), typeOf()).map { classToSignature(it) }, classToSignature(typeOf()) ).toString() @@ -37,6 +47,9 @@ inline fun inline fun signature(function: (CPointer, jobject, T, S, U, V, W) -> R): String { + if(T::class.isCPointer() || R::class.isCPointer() || S::class.isCPointer() + || U::class.isCPointer() || V::class.isCPointer() || W::class.isCPointer()) + error("CPointer classes are not currently supported") return Signature(listOf(typeOf(), typeOf(), typeOf(), typeOf(), typeOf()).map { classToSignature(it) }, classToSignature(typeOf()) ).toString() @@ -44,6 +57,10 @@ inline fun inline fun signature(function: (CPointer, jobject, T, S, U, V, W, X) -> R): String { + if(T::class.isCPointer() || R::class.isCPointer() || S::class.isCPointer() + || U::class.isCPointer() || V::class.isCPointer() || W::class.isCPointer() + || X::class.isCPointer()) + error("CPointer classes are not currently supported") return Signature(listOf(typeOf(), typeOf(), typeOf(), typeOf(), typeOf(), typeOf()).map { classToSignature(it) }, classToSignature(typeOf()) ).toString() @@ -51,6 +68,10 @@ inline fun signature(function: (CPointer, jobject, T, S, U, V, W, X, Y) -> R): String { + if(T::class.isCPointer() || R::class.isCPointer() || S::class.isCPointer() + || U::class.isCPointer() || V::class.isCPointer() || W::class.isCPointer() + || X::class.isCPointer() || Y::class.isCPointer()) + error("CPointer classes are not currently supported") return Signature(listOf(typeOf(), typeOf(), typeOf(), typeOf(), typeOf(), typeOf(), typeOf()) .map { classToSignature(it) }, classToSignature(typeOf()) diff --git a/jni-utils/src/commonMain/kotlin/io/github/landrynorris/jniutils/Utils.kt b/jni-utils/src/commonMain/kotlin/io/github/landrynorris/jniutils/Utils.kt index d91c708..05b484d 100644 --- a/jni-utils/src/commonMain/kotlin/io/github/landrynorris/jniutils/Utils.kt +++ b/jni-utils/src/commonMain/kotlin/io/github/landrynorris/jniutils/Utils.kt @@ -2,6 +2,11 @@ package io.github.landrynorris.jniutils import kotlinx.cinterop.* import platform.android.* +import kotlin.reflect.KClass + +inline fun > T.isCPointer(): Boolean { + return this == CPointer::class +} fun jboolean.toBoolean(): Boolean = (this == JNI_TRUE.toUByte()) diff --git a/sample/src/androidMain/jniLibs/arm64-v8a/libsample.so b/sample/src/androidMain/jniLibs/arm64-v8a/libsample.so index 48b3943..d638183 100755 Binary files a/sample/src/androidMain/jniLibs/arm64-v8a/libsample.so and b/sample/src/androidMain/jniLibs/arm64-v8a/libsample.so differ diff --git a/sample/src/androidMain/jniLibs/armeabi-v7a/libsample.so b/sample/src/androidMain/jniLibs/armeabi-v7a/libsample.so index 8db47f6..7f78a90 100755 Binary files a/sample/src/androidMain/jniLibs/armeabi-v7a/libsample.so and b/sample/src/androidMain/jniLibs/armeabi-v7a/libsample.so differ diff --git a/sample/src/androidMain/jniLibs/x86/libsample.so b/sample/src/androidMain/jniLibs/x86/libsample.so index 4edc59b..297cd5c 100755 Binary files a/sample/src/androidMain/jniLibs/x86/libsample.so and b/sample/src/androidMain/jniLibs/x86/libsample.so differ diff --git a/sample/src/androidMain/jniLibs/x86_64/libsample.so b/sample/src/androidMain/jniLibs/x86_64/libsample.so index b90afee..5c1c1b2 100755 Binary files a/sample/src/androidMain/jniLibs/x86_64/libsample.so and b/sample/src/androidMain/jniLibs/x86_64/libsample.so differ diff --git a/sample/src/androidMain/kotlin/io/github/landrynorris/sample/JniBridge.kt b/sample/src/androidMain/kotlin/io/github/landrynorris/sample/JniBridge.kt index 51c4278..540d045 100644 --- a/sample/src/androidMain/kotlin/io/github/landrynorris/sample/JniBridge.kt +++ b/sample/src/androidMain/kotlin/io/github/landrynorris/sample/JniBridge.kt @@ -14,6 +14,7 @@ object JniBridge { external fun doubleAll(array: DoubleArray): DoubleArray external fun callJavaFunction(value: Double) external fun createDataClass(s: String?, i: Int, d: Double, doubles: DoubleArray): Any + external fun signatureWithCType(s: String): Boolean external fun buttonClicked(ptr: Long) external fun getText(ptr: Long): String external fun createRepository(): Long diff --git a/sample/src/androidMain/kotlin/io/github/landrynorris/sample/MainActivity.kt b/sample/src/androidMain/kotlin/io/github/landrynorris/sample/MainActivity.kt index 2094934..470f390 100644 --- a/sample/src/androidMain/kotlin/io/github/landrynorris/sample/MainActivity.kt +++ b/sample/src/androidMain/kotlin/io/github/landrynorris/sample/MainActivity.kt @@ -41,6 +41,9 @@ class MainActivity: AppCompatActivity() { JniBridge.methodWithParameters(50) JniBridge.callJavaFunction(12.5) + val didThrowException = JniBridge.signatureWithCType("Something") + if(!didThrowException) error("No error when trying to get type of CPointer") + val s = "A string" val i = 200 val d = 256.5 diff --git a/sample/src/ndkMain/kotlin/io/github/landrynorris/jni/sample/Jni.kt b/sample/src/ndkMain/kotlin/io/github/landrynorris/jni/sample/Jni.kt index 9d2043a..c0bfec3 100644 --- a/sample/src/ndkMain/kotlin/io/github/landrynorris/jni/sample/Jni.kt +++ b/sample/src/ndkMain/kotlin/io/github/landrynorris/jni/sample/Jni.kt @@ -68,6 +68,15 @@ fun handleSharedClass(env: CPointer, thiz: jobject, data: jobject): j return s.toJString(env) ?: error("Unable to create JString") } +fun signatureWithCType(env: CPointer, thiz: jobject, s: jstring): jboolean { + return try { + println("Signature is ${signature(::signatureWithCType)}") + false.toJBoolean() + } catch (e: IllegalStateException) { + true.toJBoolean() + } +} + fun crash(env: CPointer, thiz: jobject, message: jstring) { val messageString = env.getString(message) env.fatalError(messageString) @@ -111,8 +120,7 @@ fun registerJniNatives(env: CPointer) { } method("createDataClass") { - signature = Signature(listOf(String, Int, Double, DoubleArray), - createSignature("java.lang.Object")).toString() + signature = Signature(listOf(String, Int, Double, DoubleArray), Object).toString() function = staticCFunction(::createDataClass) } @@ -130,6 +138,11 @@ fun registerJniNatives(env: CPointer) { signature = Signature(listOf(signature()), String).toString() function = staticCFunction(::handleSharedClass) } + + method("signatureWithCType") { + signature = Signature(listOf(String), Boolean).toString() + function = staticCFunction(::signatureWithCType) + } } println("Finished registering native methods") }