Skip to content

Commit

Permalink
Add error when trying to create a signature for a CPointer, since it'…
Browse files Browse the repository at this point in the history
…s not currently supported
  • Loading branch information
LandryNorris committed Jan 19, 2023
1 parent 3b32a34 commit b54554b
Show file tree
Hide file tree
Showing 11 changed files with 55 additions and 5 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -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")
Expand Down
Original file line number Diff line number Diff line change
@@ -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
Expand All @@ -12,7 +13,11 @@ data class Signature(val parameterClasses: List<JClass>, val returnClass: JClass
}
}

inline fun <reified T> signature() = classToSignature(typeOf<T>())
inline fun <reified T> signature() = if(T::class == CPointed::class) {
error("We can't get the type from a CPointed yet.")
} else {
classToSignature(typeOf<T>())
}

inline fun classToSignature(type: KType) = when(type) {
typeOf<Unit>() -> Void
Expand All @@ -25,13 +30,14 @@ inline fun classToSignature(type: KType) = when(type) {
typeOf<Float>() -> Float
typeOf<Double>() -> Double
typeOf<BooleanArray>() -> BooleanArray
typeOf<LongArray>() -> LongArray
typeOf<ByteArray>() -> ByteArray
typeOf<ShortArray>() -> ShortArray
typeOf<CharArray>() -> CharArray
typeOf<IntArray>() -> IntArray
typeOf<FloatArray>() -> FloatArray
typeOf<DoubleArray>() -> DoubleArray
typeOf<jobject>() -> createSignature("java.lang.Object")
typeOf<jobject>() -> Object
typeOf<jstring>() -> String
else -> createSignature(type.toString())
}
Original file line number Diff line number Diff line change
@@ -1,56 +1,77 @@
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 <reified R> signature(function: (CPointer<JNIEnvVar>, jobject) -> R): String {
if(R::class.isCPointer()) error("CPointer classes are not currently supported")
return Signature(listOf(), classToSignature(typeOf<R>())).toString()
}

inline fun <reified R, reified T> signature(function: (CPointer<JNIEnvVar>, jobject, T) -> R): String {
if(T::class.isCPointer() || R::class.isCPointer())
error("CPointer classes are not currently supported")
return Signature(listOf(classToSignature(typeOf<T>())),
classToSignature(typeOf<R>())).toString()
}

inline fun <reified R, reified T, reified S>
signature(function: (CPointer<JNIEnvVar>, 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<T>(), typeOf<S>()).map { classToSignature(it) },
classToSignature(typeOf<R>())).toString()
}

inline fun <reified R, reified T, reified S, reified U>
signature(function: (CPointer<JNIEnvVar>, 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<T>(), typeOf<S>(), typeOf<U>()).map { classToSignature(it) },
classToSignature(typeOf<R>())
).toString()
}

inline fun <reified R, reified T, reified S, reified U, reified V>
signature(function: (CPointer<JNIEnvVar>, 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<T>(), typeOf<S>(), typeOf<U>(), typeOf<V>()).map { classToSignature(it) },
classToSignature(typeOf<R>())
).toString()
}

inline fun <reified R, reified T, reified S, reified U, reified V, reified W>
signature(function: (CPointer<JNIEnvVar>, 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<T>(), typeOf<S>(), typeOf<U>(), typeOf<V>(), typeOf<W>()).map { classToSignature(it) },
classToSignature(typeOf<R>())
).toString()
}

inline fun <reified R, reified T, reified S, reified U, reified V, reified W, reified X>
signature(function: (CPointer<JNIEnvVar>, 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<T>(), typeOf<S>(), typeOf<U>(), typeOf<V>(), typeOf<W>(), typeOf<X>()).map { classToSignature(it) },
classToSignature(typeOf<R>())
).toString()
}

inline fun <reified R, reified T, reified S, reified U, reified V, reified W, reified X, reified Y>
signature(function: (CPointer<JNIEnvVar>, 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<T>(), typeOf<S>(), typeOf<U>(), typeOf<V>(), typeOf<W>(), typeOf<X>(), typeOf<Y>())
.map { classToSignature(it) },
classToSignature(typeOf<R>())
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,11 @@ package io.github.landrynorris.jniutils

import kotlinx.cinterop.*
import platform.android.*
import kotlin.reflect.KClass

inline fun <T: KClass<*>> T.isCPointer(): Boolean {
return this == CPointer::class
}

fun jboolean.toBoolean(): Boolean = (this == JNI_TRUE.toUByte())

Expand Down
Binary file modified sample/src/androidMain/jniLibs/arm64-v8a/libsample.so
Binary file not shown.
Binary file modified sample/src/androidMain/jniLibs/armeabi-v7a/libsample.so
Binary file not shown.
Binary file modified sample/src/androidMain/jniLibs/x86/libsample.so
Binary file not shown.
Binary file modified sample/src/androidMain/jniLibs/x86_64/libsample.so
Binary file not shown.
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
17 changes: 15 additions & 2 deletions sample/src/ndkMain/kotlin/io/github/landrynorris/jni/sample/Jni.kt
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,15 @@ fun handleSharedClass(env: CPointer<JNIEnvVar>, thiz: jobject, data: jobject): j
return s.toJString(env) ?: error("Unable to create JString")
}

fun signatureWithCType(env: CPointer<JNIEnvVar>, thiz: jobject, s: jstring): jboolean {
return try {
println("Signature is ${signature(::signatureWithCType)}")
false.toJBoolean()
} catch (e: IllegalStateException) {
true.toJBoolean()
}
}

fun crash(env: CPointer<JNIEnvVar>, thiz: jobject, message: jstring) {
val messageString = env.getString(message)
env.fatalError(messageString)
Expand Down Expand Up @@ -111,8 +120,7 @@ fun registerJniNatives(env: CPointer<JNIEnvVar>) {
}

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)
}

Expand All @@ -130,6 +138,11 @@ fun registerJniNatives(env: CPointer<JNIEnvVar>) {
signature = Signature(listOf(signature<SharedClass>()), String).toString()
function = staticCFunction(::handleSharedClass)
}

method("signatureWithCType") {
signature = Signature(listOf(String), Boolean).toString()
function = staticCFunction(::signatureWithCType)
}
}
println("Finished registering native methods")
}

0 comments on commit b54554b

Please sign in to comment.