diff options
author | chai <chaifix@163.com> | 2019-08-14 22:50:43 +0800 |
---|---|---|
committer | chai <chaifix@163.com> | 2019-08-14 22:50:43 +0800 |
commit | 15740faf9fe9fe4be08965098bbf2947e096aeeb (patch) | |
tree | a730ec236656cc8cab5b13f088adfaed6bb218fb /Runtime/Export/AndroidJNI.txt |
Diffstat (limited to 'Runtime/Export/AndroidJNI.txt')
-rw-r--r-- | Runtime/Export/AndroidJNI.txt | 918 |
1 files changed, 918 insertions, 0 deletions
diff --git a/Runtime/Export/AndroidJNI.txt b/Runtime/Export/AndroidJNI.txt new file mode 100644 index 0000000..fc7bd82 --- /dev/null +++ b/Runtime/Export/AndroidJNI.txt @@ -0,0 +1,918 @@ +C++RAW + + +#include "UnityPrefix.h" +#include "Runtime/Scripting/ScriptingUtility.h" +#include "Runtime/Mono/MonoBehaviour.h" +#include "Runtime/Mono/MonoScopedThreadAttach.h" + +#if UNITY_ANDROID + +#if UNITY_DEVELOPER_BUILD + static volatile bool DEBUGJNI = false; +#else + #define DEBUGJNI 0 +#endif + +#define DEBUGJNI_VERBOSE 0 + +#include "PlatformDependent/AndroidPlayer/EntryPoint.h" + + static MonoDomain* s_MonoDomain = 0; + jobject UnityJavaProxy_invoke(JNIEnv*, jobject thiz, jint delegate, jstring method, jobjectArray args) + { + ScopedThreadAttach mono(s_MonoDomain); + MonoObject* proxy = mono_gchandle_get_target(delegate); + void* params[] = {proxy, &method, &args}; + MonoObject* mresult = CallStaticMonoMethod("_AndroidJNIHelper", "InvokeJavaProxyMethod", params); + if (!mresult) + return 0; + return ExtractMonoObjectData<jobject>(mresult); + } + void UnityJavaProxy_finalize(JNIEnv*, jobject thiz, jint jdelegate) + { + ScopedThreadAttach mono(s_MonoDomain); + mono_gchandle_free(jdelegate); + } + +#if DEBUGJNI + #define SCOPED_JNI(x) DalvikAttachThreadScoped jni_env(x) +#else + #define SCOPED_JNI(x) DalvikAttachThreadScoped jni_env("AndroidJNI") +#endif + +#define JNI_GET_ID( GetIDFunc ) \ + do { \ + SCOPED_JNI(__FUNCTION__); \ + if (!jni_env) return 0; \ + string methodName = name; \ + string signature = sig; \ + if (DEBUGJNI) \ + printf_console("> %s(%08x, %s, %s)", __FUNCTION__, clazz, methodName.c_str(), signature.c_str()); \ + if (clazz == 0) \ + return 0; \ + return jni_env->GetIDFunc((jclass)clazz, methodName.c_str(), signature.c_str()); \ + } while(0) + +#define ConvertToJNIArgs() \ + int numargs = mono_array_length(args); \ + jvalue* jni_args = (jvalue*)alloca(sizeof(jvalue) * numargs); \ + for (int i = 0; i < numargs; ++i) \ + { \ + jni_args[i] = GetMonoArrayElement<jvalue>(args, i); \ + if (DEBUGJNI) \ + printf_console(">\t\t\t, %08x", jni_args[i].i); \ + } \ + if (DEBUGJNI && numargs) \ + printf_console(">\t\t\t)"); + +#define JNI_CALL_METHOD( MethodFunc, ClassOrObj ) \ + do { \ + SCOPED_JNI(__FUNCTION__); \ + if (!jni_env) return 0; \ + if (DEBUGJNI) \ + printf_console("> %s(%08x, %08x%s", __FUNCTION__, ClassOrObj, \ + (jmethodID)methodID, mono_array_length(args) ? " " : ")"); \ + if (ClassOrObj == 0 || (jmethodID)methodID == 0) \ + return 0; \ + ConvertToJNIArgs(); \ + return jni_env->MethodFunc(ClassOrObj, (jmethodID)methodID, jni_args); \ + } while(0) + +#define JNI_CALL_VOID_METHOD( MethodFunc, ClassOrObj ) \ + do { \ + SCOPED_JNI(__FUNCTION__); \ + if (!jni_env) return; \ + if (DEBUGJNI) \ + printf_console("> %s(%08x, %08x%s", __FUNCTION__, ClassOrObj, \ + (jmethodID)methodID, mono_array_length(args) ? " " : ")"); \ + if (ClassOrObj == 0 || (jmethodID)methodID == 0) \ + return; \ + ConvertToJNIArgs(); \ + jni_env->MethodFunc(ClassOrObj, (jmethodID)methodID, jni_args); \ + } while(0) + +#define JNI_GET_FIELD( FieldFunc, ClassOrObj ) \ + do { \ + SCOPED_JNI(__FUNCTION__); \ + if (!jni_env) return 0; \ + if (DEBUGJNI) \ + printf_console("> %s(%08x)", __FUNCTION__, ClassOrObj); \ + if (ClassOrObj == 0 || (jmethodID)fieldID == 0) \ + return 0; \ + return jni_env->FieldFunc(ClassOrObj, (jfieldID)fieldID); \ + } while(0) + +#define JNI_SET_FIELD( FieldFunc, ClassOrObj, Value ) \ + do { \ + SCOPED_JNI(__FUNCTION__); \ + if (!jni_env) return; \ + if (DEBUGJNI) \ + printf_console("> %s(%08x)", __FUNCTION__, ClassOrObj); \ + if (ClassOrObj == 0 || (jmethodID)fieldID == 0) \ + return; \ + jni_env->FieldFunc(ClassOrObj, (jfieldID)fieldID, Value); \ + } while(0) + +#define JNI_PASS_VOID_VOID( Func ) \ + do { \ + SCOPED_JNI(__FUNCTION__); \ + if (!jni_env) return; \ + if (DEBUGJNI) \ + printf_console("> %s()", __FUNCTION__); \ + jni_env->Func(); \ + } while(0) + +#define JNI_PASS_RETV_VOID( Func ) \ + do { \ + SCOPED_JNI(__FUNCTION__); \ + if (!jni_env) return 0; \ + if (DEBUGJNI) \ + printf_console("> %s()", __FUNCTION__); \ + return jni_env->Func(); \ + } while(0) + +#define JNI_PASS_VOID_ARGS( Func, ...) \ + do { \ + SCOPED_JNI(__FUNCTION__); \ + if (!jni_env) return; \ + if (DEBUGJNI) \ + printf_console("> %s()", __FUNCTION__); \ + jni_env->Func(__VA_ARGS__); \ + } while(0) + +#define JNI_PASS_RETV_ARGS( Func, ...) \ + do { \ + SCOPED_JNI(__FUNCTION__); \ + if (!jni_env) return 0; \ + if (DEBUGJNI) \ + printf_console("> %s()", __FUNCTION__); \ + return jni_env->Func(__VA_ARGS__); \ + } while(0) + +#define JNI_GET_JSTR_FIELD( FieldFunc, ClassOrObj ) \ + do { \ + SCOPED_JNI(__FUNCTION__); \ + if (!jni_env) return SCRIPTING_NULL; \ + if (DEBUGJNI) \ + printf_console("> %s(%08x)", __FUNCTION__, ClassOrObj); \ + if (ClassOrObj == 0 || (jmethodID)fieldID == 0) \ + return SCRIPTING_NULL; \ + jstring str = (jstring)jni_env->FieldFunc(ClassOrObj, (jfieldID)fieldID); \ + if (str == 0 || jni_env->ExceptionCheck()) return SCRIPTING_NULL; \ + const char* cstring = jni_env->GetStringUTFChars(str, 0); \ + if (cstring == 0 || jni_env->ExceptionCheck()) \ + { \ + jni_env->ReleaseStringUTFChars(str, cstring); \ + jni_env->DeleteLocalRef(str); \ + return SCRIPTING_NULL; \ + } \ + MonoString* mstring = scripting_string_new(cstring); \ + jni_env->ReleaseStringUTFChars(str, cstring); \ + jni_env->DeleteLocalRef(str); \ + return mstring; \ + } while(0) + +#define JNI_CALL_JSTR_METHOD( MethodFunc, ClassOrObj ) \ + do { \ + SCOPED_JNI(__FUNCTION__); \ + if (!jni_env) return SCRIPTING_NULL; \ + if (DEBUGJNI) \ + printf_console("> %s(%08x, %08x%s", __FUNCTION__, ClassOrObj, \ + (jmethodID)methodID, mono_array_length(args) ? " " : ")"); \ + if (ClassOrObj == 0 || (jmethodID)methodID == 0) \ + return SCRIPTING_NULL; \ + ConvertToJNIArgs(); \ + jstring str = (jstring)jni_env->MethodFunc(ClassOrObj, (jmethodID)methodID, jni_args); \ + if (str == 0 || jni_env->ExceptionCheck()) return SCRIPTING_NULL; \ + const char* cstring = jni_env->GetStringUTFChars(str, 0); \ + if (cstring == 0 || jni_env->ExceptionCheck()) \ + { \ + jni_env->ReleaseStringUTFChars(str, cstring); \ + jni_env->DeleteLocalRef(str); \ + return SCRIPTING_NULL; \ + } \ + MonoString* mstring = scripting_string_new(cstring); \ + jni_env->ReleaseStringUTFChars(str, cstring); \ + jni_env->DeleteLocalRef(str); \ + return mstring; \ + } while(0) + +#define JNI_NEW_ARRAY( NewArrayType, Type, ArrayType ) \ + do { \ + SCOPED_JNI(__FUNCTION__); \ + if (!jni_env) return SCRIPTING_NULL; \ + int size = mono_array_length(array); \ + ArrayType jni_array = jni_env->New ## NewArrayType ## Array(size); \ + if (jni_array == 0 || jni_env->ExceptionCheck()) return SCRIPTING_NULL; \ + for (int i = 0; i < size; ++i) \ + { \ + Type val = GetMonoArrayElement<Type>(array, i); \ + jni_env->Set ## NewArrayType ## ArrayRegion(jni_array, i, 1, &val); \ + if (jni_env->ExceptionCheck()) return SCRIPTING_NULL; \ + } \ + return jni_array; \ + } while(0) + +#define JNI_GET_ARRAY( GetArrayType, Type, ArrayType, ArrayClass ) \ + do { \ + SCOPED_JNI(__FUNCTION__); \ + if (!jni_env) return SCRIPTING_NULL; \ + jsize length = jni_env->GetArrayLength((jarray)array); \ + if (jni_env->ExceptionCheck()) return SCRIPTING_NULL; \ + MonoArray* csarray = mono_array_new(mono_domain_get(), ArrayClass, length); \ + Type* mem = jni_env->Get ## GetArrayType ## ArrayElements((ArrayType)array, 0); \ + if (jni_env->ExceptionCheck()) return SCRIPTING_NULL; \ + for (int i = 0; i < length; ++i) \ + Scripting::SetScriptingArrayElement<Type>(csarray, i, mem[i]); \ + jni_env->Release ## GetArrayType ## ArrayElements((ArrayType)array, mem, JNI_ABORT); \ + return csarray; \ + } while(0) + +#define JNI_GET_ARRAY_ELEMENT( GetArrayType, Type, ArrayType ) \ + do { \ + SCOPED_JNI(__FUNCTION__); \ + if (!jni_env) return 0; \ + Type val; \ + jni_env->Get ## GetArrayType ## ArrayRegion((ArrayType)array, index, 1, &val); \ + return val; \ + } while(0) + +#define JNI_SET_ARRAY_ELEMENT( SetArrayType, Type, ArrayType ) \ + do { \ + SCOPED_JNI(__FUNCTION__); \ + if (!jni_env) return; \ + jni_env->Get ## SetArrayType ## ArrayRegion((ArrayType)array, index, 1, &val); \ + } while(0) + +struct jStringWrapper +{ + std::string cString; + jstring javaString; + jStringWrapper(ICallString& cs) + : javaString(0) + { + cString = cs; + if (DEBUGJNI_VERBOSE) + printf_console("> [%s](\"%s\")", __FUNCTION__, cString.c_str()); + } + + ~jStringWrapper() + { + if (DEBUGJNI_VERBOSE) + printf_console("> [%s](\"%s\")", __FUNCTION__, cString.c_str()); + if (!javaString) + return; + SCOPED_JNI(__FUNCTION__); + if (!jni_env) return; + jni_env->DeleteLocalRef(javaString); + } + + operator jstring() + { + if (DEBUGJNI_VERBOSE) + printf_console("> [%s](\"%s\")", __FUNCTION__, cString.c_str()); + SCOPED_JNI(__FUNCTION__); + if (!jni_env) return 0; + javaString = jni_env->NewStringUTF(cString.c_str()); + return javaString; + } + operator const char*() + { + if (DEBUGJNI_VERBOSE) + printf_console("> [%s](\"%s\")", __FUNCTION__, cString.c_str()); + return cString.c_str(); + } +}; + +#else // UNITY_ANDROID + +typedef void* jobject; +typedef void* jclass; + +#define JNI_GET_ID( GetIDFunc ) do { return 0; } while(0) +#define JNI_CALL_METHOD( MethodFunc, ClassOrObj ) do { (void)ClassOrObj; return 0; } while(0) +#define JNI_CALL_VOID_METHOD( MethodFunc, ClassOrObj ) do { (void)ClassOrObj; } while(0) +#define JNI_GET_FIELD( FieldFunc, ClassOrObj ) do { (void)ClassOrObj; return 0; } while(0) +#define JNI_GET_JSTR_FIELD( FieldFunc, ClassOrObj ) do { (void)ClassOrObj; return SCRIPTING_NULL; } while(0) +#define JNI_SET_FIELD( FieldFunc, ClassOrObj, Value ) do { (void)ClassOrObj; (void)Value; } while(0) +#define JNI_PASS_VOID_VOID( Func ) do { ; } while(0) +#define JNI_PASS_RETV_VOID( Func) do { return 0; } while(0) +#define JNI_PASS_VOID_ARGS( Func, ...) do { ; } while(0) +#define JNI_PASS_RETV_ARGS( Func, ...) do { return 0; } while(0) +#define JNI_CALL_JSTR_METHOD( MethodFunc, ClassOrObj ) do { (void)ClassOrObj; return SCRIPTING_NULL; } while(0) +#define JNI_NEW_ARRAY( NewArrayFunc, Type, ArrayType ) do { return SCRIPTING_NULL; } while(0) +#define JNI_GET_ARRAY( GetArrayType, Type, ArrayType, ArrayClass ) do { return SCRIPTING_NULL; } while(0) +#define JNI_GET_ARRAY_ELEMENT( GetArrayType, Type, ArrayType ) do { return 0; } while(0) +#define JNI_SET_ARRAY_ELEMENT( SetArrayType, Type, ArrayType ) do { ; } while(0) + +#endif + +CSRAW +#if UNITY_EDITOR || UNITY_ANDROID +using System; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; + +namespace UnityEngine +{ + [StructLayout(LayoutKind.Explicit)] + public struct jvalue + { + [FieldOffset(0)] public bool z; + [FieldOffset(0)] public byte b; + [FieldOffset(0)] public char c; + [FieldOffset(0)] public short s; + [FieldOffset(0)] public int i; + [FieldOffset(0)] public long j; + [FieldOffset(0)] public float f; + [FieldOffset(0)] public double d; + [FieldOffset(0)] public System.IntPtr l; + } + +// Helper interface for JNI interaction; signature creation and method lookups +CONDITIONAL !UNITY_WINRT +CLASS AndroidJNIHelper + + CSRAW private AndroidJNIHelper() {} + + // Set /debug/ to true to log calls through the AndroidJNIHelper + CUSTOM_PROP static bool debug + { + #if UNITY_ANDROID && UNITY_DEVELOPER_BUILD + return DEBUGJNI; + #else + return false; + #endif + } + { + #if UNITY_ANDROID && UNITY_DEVELOPER_BUILD + DEBUGJNI = value; + SCOPED_JNI(__FUNCTION__); + if (!jni_env) return; + jclass cls_up = jni_env->FindClass("com/unity3d/player/ReflectionHelper"); + if (!cls_up || jni_env->ExceptionCheck()) + return; + jfieldID fid_get = jni_env->GetStaticFieldID(cls_up, "LOG", "Z"); + if (!fid_get || jni_env->ExceptionCheck()) + { + jni_env->DeleteLocalRef(cls_up); + return; + } + jni_env->SetStaticBooleanField(cls_up, fid_get, value); + jni_env->DeleteLocalRef(cls_up); + #endif + } + + // Scans a particular Java class for a constructor method matching a signature. + CSRAW public static IntPtr GetConstructorID(IntPtr javaClass, string signature = "") + { + return _AndroidJNIHelper.GetConstructorID(javaClass, signature); + } + + // Scans a particular Java class for a method matching a name and a signature. + CSRAW public static IntPtr GetMethodID(IntPtr javaClass, string methodName, string signature = "", bool isStatic = false) + { + return _AndroidJNIHelper.GetMethodID(javaClass, methodName, signature, isStatic); + } + + CSRAW public static IntPtr GetFieldID(IntPtr javaClass, string fieldName, string signature = "", bool isStatic = false) + { + return _AndroidJNIHelper.GetFieldID(javaClass, fieldName, signature, isStatic); + } + + // Creates a UnityJavaRunnable object (implements java.lang.Runnable). + CSRAW public static IntPtr CreateJavaRunnable(AndroidJavaRunnable jrunnable) + { + return _AndroidJNIHelper.CreateJavaRunnable(jrunnable); + } + + // Creates a UnityJavaProxy object (implements jinterface). + THREAD_SAFE CUSTOM static IntPtr CreateJavaProxy(AndroidJavaProxy proxy) + { + #if UNITY_ANDROID + s_MonoDomain = mono_domain_get(); + + int gcHandle = mono_gchandle_new(proxy, 0); + void* params[] = { &gcHandle, proxy }; + MonoException* exception; + MonoObject* result = CallStaticMonoMethod("_AndroidJNIHelper", "CreateJavaProxy", params, &exception); + if (exception) + { + mono_gchandle_free(gcHandle); + mono_raise_exception(exception); + return 0; + } + return ExtractMonoObjectData<jobject>(result); + #else + return 0; + #endif + } + + // Creates a Java array from a managed array + CSRAW public static IntPtr ConvertToJNIArray(System.Array array) + { + return _AndroidJNIHelper.ConvertToJNIArray(array); + } + + // Creates the parameter array to be used as argument list when invoking Java code through CallMethod() in AndroidJNI. + CSRAW public static jvalue[] CreateJNIArgArray(object[] args) + { + return _AndroidJNIHelper.CreateJNIArgArray(args); + } + + // Deletes any local jni references previously allocated by CreateJNIArgArray() + // + // @param jniArgs the array returned by CreateJNIArgArray() + // @param args the array of arguments used as a parameter to CreateJNIArgArray() + // + CSRAW public static void DeleteJNIArgArray(object[] args, jvalue[] jniArgs) + { + _AndroidJNIHelper.DeleteJNIArgArray(args, jniArgs); + } + + // Get a JNI method ID for a constructor based on calling arguments. + // Scans a particular Java class for a constructor method matching a signature based on passed arguments. + // The signature comparison is done to allow for sub-/base-classes of the class types. + // + // @param javaClass Raw JNI Java class object (obtained by calling AndroidJNI.FindClass). + // @param args Array with parameters to be passed to the constructor when invoked. + // + CSRAW public static System.IntPtr GetConstructorID(System.IntPtr jclass, object[] args) + { + return _AndroidJNIHelper.GetConstructorID(jclass, args); + } + // Get a JNI method ID based on calling arguments. + CSRAW public static System.IntPtr GetMethodID(System.IntPtr jclass, string methodName, object[] args, bool isStatic) + { + return _AndroidJNIHelper.GetMethodID(jclass, methodName, args, isStatic); + } + + // Creates the JNI signature string for particular object type + CSRAW public static string GetSignature(object obj) + { + return _AndroidJNIHelper.GetSignature(obj); + } + + // Creates the JNI signature string for an object parameter list. + CSRAW public static string GetSignature(object[] args) + { + return _AndroidJNIHelper.GetSignature(args); + } + + //=================================================================== + + // Creates a managed array from a Java array + CSRAW public static ArrayType ConvertFromJNIArray<ArrayType>(IntPtr array) + { + return _AndroidJNIHelper.ConvertFromJNIArray<ArrayType>(array); + } + + // Get a JNI method ID based on calling arguments. + CSRAW public static System.IntPtr GetMethodID<ReturnType>(System.IntPtr jclass, string methodName, object[] args, bool isStatic) + { + return _AndroidJNIHelper.GetMethodID<ReturnType>(jclass, methodName, args, isStatic); + } + + // Get a JNI field ID based on type detection. Generic parameter represents the field type. + CSRAW public static System.IntPtr GetFieldID<FieldType>(System.IntPtr jclass, string fieldName, bool isStatic) + { + return _AndroidJNIHelper.GetFieldID<FieldType>(jclass, fieldName, isStatic); + } + + // Creates the JNI signature string for an object parameter list. + CSRAW public static string GetSignature<ReturnType>(object[] args) + { + return _AndroidJNIHelper.GetSignature<ReturnType>(args); + } +END + +// 'Raw' JNI interface to Android Dalvik (Java) VM from Mono (CS/JS) +CONDITIONAL !UNITY_WINRT +CLASS AndroidJNI + + CSRAW private AndroidJNI() {} + + // Attaches the current thread to a Java (Dalvik) VM. + THREAD_SAFE CUSTOM static int AttachCurrentThread() + { + #if UNITY_ANDROID + JavaVM* vm = GetJavaVm(); + Assert(vm); + JNIEnv* env; + return vm->AttachCurrentThread(&env, 0); + #else + return 0; + #endif + } + // Detaches the current thread from a Java (Dalvik) VM. + THREAD_SAFE CUSTOM static int DetachCurrentThread() + { + #if UNITY_ANDROID + JavaVM* vm = GetJavaVm(); + Assert(vm); + return vm->DetachCurrentThread(); + #else + return 0; + #endif + } + + // Returns the version of the native method interface. + THREAD_SAFE CUSTOM static int GetVersion() { JNI_PASS_RETV_VOID( GetVersion ); } + + // This function loads a locally-defined class. + THREAD_SAFE CUSTOM static IntPtr FindClass(string name) { JNI_PASS_RETV_ARGS( FindClass, jStringWrapper(name) ); } + + // Converts a <tt>java.lang.reflect.Method</tt> or <tt>java.lang.reflect.Constructor</tt> object to a method ID. + THREAD_SAFE CUSTOM static IntPtr FromReflectedMethod(IntPtr refMethod) { JNI_PASS_RETV_ARGS( FromReflectedMethod, (jobject)refMethod ); } + // Converts a <tt>java.lang.reflect.Field</tt> to a field ID. + THREAD_SAFE CUSTOM static IntPtr FromReflectedField(IntPtr refField) { JNI_PASS_RETV_ARGS( FromReflectedField, (jobject)refField ); } + // Converts a method ID derived from clazz to a <tt>java.lang.reflect.Method</tt> or <tt>java.lang.reflect.Constructor</tt> object. + THREAD_SAFE CUSTOM static IntPtr ToReflectedMethod(IntPtr clazz, IntPtr methodID, bool isStatic) { JNI_PASS_RETV_ARGS( ToReflectedMethod, (jclass)clazz, (jmethodID)methodID, isStatic ); } + // Converts a field ID derived from cls to a <tt>java.lang.reflect.Field</tt> object. + THREAD_SAFE CUSTOM static IntPtr ToReflectedField(IntPtr clazz, IntPtr fieldID, bool isStatic) { JNI_PASS_RETV_ARGS( ToReflectedField, (jclass)clazz, (jfieldID)fieldID, isStatic ); } + + // If <tt>clazz</tt> represents any class other than the class <tt>Object</tt>, then this function returns the object that represents the superclass of the class specified by <tt>clazz</tt>. + THREAD_SAFE CUSTOM static IntPtr GetSuperclass(IntPtr clazz) { JNI_PASS_RETV_ARGS( GetSuperclass, (jclass)clazz ); } + // Determines whether an object of <tt>clazz1</tt> can be safely cast to <tt>clazz2</tt>. + THREAD_SAFE CUSTOM static bool IsAssignableFrom(IntPtr clazz1, IntPtr clazz2) { JNI_PASS_RETV_ARGS( IsAssignableFrom, (jclass)clazz1, (jclass)clazz2 ); } + + // Causes a <tt>java.lang.Throwable</tt> object to be thrown. + THREAD_SAFE CUSTOM static int Throw(IntPtr obj) { JNI_PASS_RETV_ARGS( Throw, (jthrowable)obj ); } + // Constructs an exception object from the specified class with the <tt>message</tt> specified by message and causes that exception to be thrown. + THREAD_SAFE CUSTOM static int ThrowNew(IntPtr clazz, string message) { JNI_PASS_RETV_ARGS( ThrowNew, (jclass)clazz, jStringWrapper(message) ); } + // Determines if an exception is being thrown + THREAD_SAFE CUSTOM static IntPtr ExceptionOccurred() { JNI_PASS_RETV_VOID( ExceptionOccurred ); } + // Prints an exception and a backtrace of the stack to the <tt>logcat</tt> + THREAD_SAFE CUSTOM static void ExceptionDescribe() { JNI_PASS_VOID_VOID( ExceptionDescribe ); } + // Clears any exception that is currently being thrown. + THREAD_SAFE CUSTOM static void ExceptionClear() { JNI_PASS_VOID_VOID( ExceptionClear ); } + // Raises a fatal error and does not expect the VM to recover. This function does not return. + THREAD_SAFE CUSTOM static void FatalError(string message) { JNI_PASS_VOID_ARGS( FatalError, jStringWrapper(message) ); } + + // Creates a new local reference frame, in which at least a given number of local references can be created. + THREAD_SAFE CUSTOM static int PushLocalFrame(int capacity) { JNI_PASS_RETV_ARGS( PushLocalFrame, capacity ); } + // Pops off the current local reference frame, frees all the local references, and returns a local reference in the previous local reference frame for the given <tt>result</tt> object. + THREAD_SAFE CUSTOM static IntPtr PopLocalFrame(IntPtr result) { JNI_PASS_RETV_ARGS( PopLocalFrame, (jobject)result ); } + + // Creates a new global reference to the object referred to by the <tt>obj</tt> argument. + THREAD_SAFE CUSTOM static IntPtr NewGlobalRef(IntPtr obj) { JNI_PASS_RETV_ARGS( NewGlobalRef, (jobject)obj ); } + // Deletes the global reference pointed to by <tt>obj</tt>. + THREAD_SAFE CUSTOM static void DeleteGlobalRef(IntPtr obj) { JNI_PASS_VOID_ARGS( DeleteGlobalRef, (jobject)obj ); } + // Creates a new local reference that refers to the same object as <tt>obj</tt>. + THREAD_SAFE CUSTOM static IntPtr NewLocalRef(IntPtr obj) { JNI_PASS_RETV_ARGS( NewLocalRef, (jobject)obj ); } + // Deletes the local reference pointed to by <tt>obj</tt>. + THREAD_SAFE CUSTOM static void DeleteLocalRef(IntPtr obj) { JNI_PASS_VOID_ARGS( DeleteLocalRef, (jobject)obj ); } + // Tests whether two references refer to the same Java object. + THREAD_SAFE CUSTOM static bool IsSameObject(IntPtr obj1, IntPtr obj2) { JNI_PASS_RETV_ARGS( IsSameObject, (jobject)obj1, (jobject)obj2 ); } + + // Ensures that at least a given number of local references can be created in the current thread. + THREAD_SAFE CUSTOM static int EnsureLocalCapacity(int capacity) { JNI_PASS_RETV_ARGS( EnsureLocalCapacity, capacity ); } + + + //------------------------------------------- + + // Allocates a new Java object without invoking any of the constructors for the object. + THREAD_SAFE CUSTOM static IntPtr AllocObject(IntPtr clazz) { JNI_PASS_RETV_ARGS( AllocObject, (jclass)clazz ); } + // Constructs a new Java object. The method ID indicates which constructor method to invoke. This ID must be obtained by calling GetMethodID() with <init> as the method name and void (V) as the return type. + THREAD_SAFE CUSTOM static IntPtr NewObject(IntPtr clazz, IntPtr methodID, jvalue[] args) { JNI_CALL_METHOD( NewObjectA, (jclass)clazz ); } + + // Returns the class of an object. + THREAD_SAFE CUSTOM static IntPtr GetObjectClass(IntPtr obj) { JNI_PASS_RETV_ARGS( GetObjectClass, (jobject)obj ); } + // Tests whether an object is an instance of a class. + THREAD_SAFE CUSTOM static bool IsInstanceOf(IntPtr obj, IntPtr clazz){ JNI_PASS_RETV_ARGS( IsInstanceOf, (jobject)obj, (jclass)clazz ); } + + // Returns the method ID for an instance (nonstatic) method of a class or interface. + THREAD_SAFE CUSTOM static IntPtr GetMethodID(IntPtr clazz, string name, string sig) { JNI_GET_ID(GetMethodID); } + // Returns the field ID for an instance (nonstatic) field of a class. + THREAD_SAFE CUSTOM static IntPtr GetFieldID(IntPtr clazz, string name, string sig) { JNI_GET_ID(GetFieldID); } + // Returns the method ID for a static method of a class. + THREAD_SAFE CUSTOM static IntPtr GetStaticMethodID(IntPtr clazz, string name, string sig) { JNI_GET_ID(GetStaticMethodID); } + // Returns the field ID for a static field of a class. + THREAD_SAFE CUSTOM static IntPtr GetStaticFieldID(IntPtr clazz, string name, string sig) { JNI_GET_ID(GetStaticFieldID); } + + // Constructs a new <tt>java.lang.String</tt> object from an array of characters in modified UTF-8 encoding. + THREAD_SAFE CUSTOM static IntPtr NewStringUTF(string bytes) { JNI_PASS_RETV_ARGS( NewStringUTF, jStringWrapper(bytes) ); } + // Returns the length in bytes of the modified UTF-8 representation of a string. + THREAD_SAFE CUSTOM static int GetStringUTFLength(IntPtr str) { JNI_PASS_RETV_ARGS( GetStringUTFLength, (jstring) str); } + // Returns a managed string object representing the string in modified UTF-8 encoding. + THREAD_SAFE CUSTOM static string GetStringUTFChars(IntPtr str) + { + #if UNITY_ANDROID + SCOPED_JNI(__FUNCTION__); + if (!jni_env) return 0; + if (DEBUGJNI) + printf_console("> %s()", __FUNCTION__); + const char* cstring = jni_env->GetStringUTFChars((jstring)str, 0); + if (cstring == 0 || jni_env->ExceptionCheck()) + { + jni_env->ReleaseStringUTFChars((jstring)str, cstring); + return 0; + } + MonoString* mstring = scripting_string_new(cstring); + jni_env->ReleaseStringUTFChars((jstring)str, cstring); + return mstring; + #else + return SCRIPTING_NULL; + #endif + } + + //--------------------------------------------- + + // Calls an instance (nonstatic) Java method defined by <tt>methodID</tt>, optionally passing an array of arguments (<tt>args</tt>) to the method. + THREAD_SAFE CUSTOM static string CallStringMethod(IntPtr obj, IntPtr methodID, jvalue[] args) { JNI_CALL_JSTR_METHOD(CallObjectMethodA, (jobject)obj); } + // Calls an instance (nonstatic) Java method defined by <tt>methodID</tt>, optionally passing an array of arguments (<tt>args</tt>) to the method. + THREAD_SAFE CUSTOM static IntPtr CallObjectMethod(IntPtr obj, IntPtr methodID, jvalue[] args) { JNI_CALL_METHOD( CallObjectMethodA, (jobject)obj ); } + // Calls an instance (nonstatic) Java method defined by <tt>methodID</tt>, optionally passing an array of arguments (<tt>args</tt>) to the method. + THREAD_SAFE CUSTOM static Int32 CallIntMethod(IntPtr obj, IntPtr methodID, jvalue[] args) { JNI_CALL_METHOD( CallIntMethodA, (jobject)obj ); } + // Calls an instance (nonstatic) Java method defined by <tt>methodID</tt>, optionally passing an array of arguments (<tt>args</tt>) to the method. + THREAD_SAFE CUSTOM static bool CallBooleanMethod(IntPtr obj, IntPtr methodID, jvalue[] args) { JNI_CALL_METHOD( CallBooleanMethodA, (jobject)obj ); } + // Calls an instance (nonstatic) Java method defined by <tt>methodID</tt>, optionally passing an array of arguments (<tt>args</tt>) to the method. + THREAD_SAFE CUSTOM static Int16 CallShortMethod(IntPtr obj, IntPtr methodID, jvalue[] args) { JNI_CALL_METHOD( CallShortMethodA, (jobject)obj ); } + // Calls an instance (nonstatic) Java method defined by <tt>methodID</tt>, optionally passing an array of arguments (<tt>args</tt>) to the method. + THREAD_SAFE CUSTOM static Byte CallByteMethod(IntPtr obj, IntPtr methodID, jvalue[] args) { JNI_CALL_METHOD( CallByteMethodA, (jobject)obj ); } + // Calls an instance (nonstatic) Java method defined by <tt>methodID</tt>, optionally passing an array of arguments (<tt>args</tt>) to the method. + THREAD_SAFE CUSTOM static Char CallCharMethod(IntPtr obj, IntPtr methodID, jvalue[] args) { JNI_CALL_METHOD( CallCharMethodA, (jobject)obj ); } + // Calls an instance (nonstatic) Java method defined by <tt>methodID</tt>, optionally passing an array of arguments (<tt>args</tt>) to the method. + THREAD_SAFE CUSTOM static float CallFloatMethod(IntPtr obj, IntPtr methodID, jvalue[] args) { JNI_CALL_METHOD( CallFloatMethodA, (jobject)obj ); } + // Calls an instance (nonstatic) Java method defined by <tt>methodID</tt>, optionally passing an array of arguments (<tt>args</tt>) to the method. + THREAD_SAFE CUSTOM static double CallDoubleMethod(IntPtr obj, IntPtr methodID, jvalue[] args) { JNI_CALL_METHOD( CallDoubleMethodA, (jobject)obj ); } + // Calls an instance (nonstatic) Java method defined by <tt>methodID</tt>, optionally passing an array of arguments (<tt>args</tt>) to the method. + THREAD_SAFE CUSTOM static Int64 CallLongMethod(IntPtr obj, IntPtr methodID, jvalue[] args) { JNI_CALL_METHOD( CallLongMethodA, (jobject)obj ); } + // Calls an instance (nonstatic) Java method defined by <tt>methodID</tt>, optionally passing an array of arguments (<tt>args</tt>) to the method. + THREAD_SAFE CUSTOM static void CallVoidMethod(IntPtr obj, IntPtr methodID, jvalue[] args) { JNI_CALL_VOID_METHOD( CallVoidMethodA, (jobject)obj ); } + + //--------------------------------------------- + + // This function returns the value of an instance (nonstatic) field of an object. + THREAD_SAFE CUSTOM static string GetStringField(IntPtr obj, IntPtr fieldID) { JNI_GET_JSTR_FIELD( GetObjectField, (jobject)obj ); } + // This function returns the value of an instance (nonstatic) field of an object. + THREAD_SAFE CUSTOM static IntPtr GetObjectField(IntPtr obj, IntPtr fieldID) { JNI_GET_FIELD( GetObjectField, (jobject)obj ); } + // This function returns the value of an instance (nonstatic) field of an object. + THREAD_SAFE CUSTOM static bool GetBooleanField(IntPtr obj, IntPtr fieldID) { JNI_GET_FIELD( GetBooleanField, (jobject)obj ); } + // This function returns the value of an instance (nonstatic) field of an object. + THREAD_SAFE CUSTOM static Byte GetByteField(IntPtr obj, IntPtr fieldID) { JNI_GET_FIELD( GetByteField, (jobject)obj ); } + // This function returns the value of an instance (nonstatic) field of an object. + THREAD_SAFE CUSTOM static Char GetCharField(IntPtr obj, IntPtr fieldID) { JNI_GET_FIELD( GetCharField, (jobject)obj ); } + // This function returns the value of an instance (nonstatic) field of an object. + THREAD_SAFE CUSTOM static Int16 GetShortField(IntPtr obj, IntPtr fieldID) { JNI_GET_FIELD( GetShortField, (jobject)obj ); } + // This function returns the value of an instance (nonstatic) field of an object. + THREAD_SAFE CUSTOM static Int32 GetIntField(IntPtr obj, IntPtr fieldID) { JNI_GET_FIELD( GetIntField, (jobject)obj ); } + // This function returns the value of an instance (nonstatic) field of an object. + THREAD_SAFE CUSTOM static Int64 GetLongField(IntPtr obj, IntPtr fieldID) { JNI_GET_FIELD( GetLongField, (jobject)obj ); } + // This function returns the value of an instance (nonstatic) field of an object. + THREAD_SAFE CUSTOM static float GetFloatField(IntPtr obj, IntPtr fieldID) { JNI_GET_FIELD( GetFloatField, (jobject)obj ); } + // This function returns the value of an instance (nonstatic) field of an object. + THREAD_SAFE CUSTOM static double GetDoubleField(IntPtr obj, IntPtr fieldID) { JNI_GET_FIELD( GetDoubleField, (jobject)obj ); } + + //--------------------------------------------- + + // This function sets the value of an instance (nonstatic) field of an object. + THREAD_SAFE CUSTOM static void SetStringField(IntPtr obj, IntPtr fieldID, string val) { JNI_PASS_VOID_ARGS( SetObjectField, (jobject)obj, (jfieldID)fieldID, jStringWrapper(val) ); } + // This function sets the value of an instance (nonstatic) field of an object. + THREAD_SAFE CUSTOM static void SetObjectField(IntPtr obj, IntPtr fieldID, IntPtr val) { JNI_SET_FIELD( SetObjectField, (jobject)obj, (jobject)val ); } + // This function sets the value of an instance (nonstatic) field of an object. + THREAD_SAFE CUSTOM static void SetBooleanField(IntPtr obj, IntPtr fieldID, bool val) { JNI_SET_FIELD( SetBooleanField, (jobject)obj, val ); } + // This function sets the value of an instance (nonstatic) field of an object. + THREAD_SAFE CUSTOM static void SetByteField(IntPtr obj, IntPtr fieldID, Byte val) { JNI_SET_FIELD( SetByteField, (jobject)obj, val ); } + // This function sets the value of an instance (nonstatic) field of an object. + THREAD_SAFE CUSTOM static void SetCharField(IntPtr obj, IntPtr fieldID, Char val) { JNI_SET_FIELD( SetCharField, (jobject)obj, val ); } + // This function sets the value of an instance (nonstatic) field of an object. + THREAD_SAFE CUSTOM static void SetShortField(IntPtr obj, IntPtr fieldID, Int16 val) { JNI_SET_FIELD( SetShortField, (jobject)obj, val ); } + // This function sets the value of an instance (nonstatic) field of an object. + THREAD_SAFE CUSTOM static void SetIntField(IntPtr obj, IntPtr fieldID, Int32 val) { JNI_SET_FIELD( SetIntField, (jobject)obj, val ); } + // This function sets the value of an instance (nonstatic) field of an object. + THREAD_SAFE CUSTOM static void SetLongField(IntPtr obj, IntPtr fieldID, Int64 val) { JNI_SET_FIELD( SetLongField, (jobject)obj, val ); } + // This function sets the value of an instance (nonstatic) field of an object. + THREAD_SAFE CUSTOM static void SetFloatField(IntPtr obj, IntPtr fieldID, float val) { JNI_SET_FIELD( SetFloatField, (jobject)obj, val ); } + // This function sets the value of an instance (nonstatic) field of an object. + THREAD_SAFE CUSTOM static void SetDoubleField(IntPtr obj, IntPtr fieldID, double val) { JNI_SET_FIELD( SetDoubleField, (jobject)obj, val ); } + + + //--------------------------------------------- + + // Invokes a static method on a Java object, according to the specified <tt>methodID</tt>, optionally passing an array of arguments (<tt>args</tt>) to the method. + THREAD_SAFE CUSTOM static string CallStaticStringMethod(IntPtr clazz, IntPtr methodID, jvalue[] args) { JNI_CALL_JSTR_METHOD(CallStaticObjectMethodA, (jclass)clazz); } + // Invokes a static method on a Java object, according to the specified <tt>methodID</tt>, optionally passing an array of arguments (<tt>args</tt>) to the method. + THREAD_SAFE CUSTOM static IntPtr CallStaticObjectMethod(IntPtr clazz, IntPtr methodID, jvalue[] args) { JNI_CALL_METHOD( CallStaticObjectMethodA, (jclass)clazz ); } + // Invokes a static method on a Java object, according to the specified <tt>methodID</tt>, optionally passing an array of arguments (<tt>args</tt>) to the method. + THREAD_SAFE CUSTOM static Int32 CallStaticIntMethod(IntPtr clazz, IntPtr methodID, jvalue[] args) { JNI_CALL_METHOD( CallStaticIntMethodA, (jclass)clazz ); } + // Invokes a static method on a Java object, according to the specified <tt>methodID</tt>, optionally passing an array of arguments (<tt>args</tt>) to the method. + THREAD_SAFE CUSTOM static bool CallStaticBooleanMethod(IntPtr clazz, IntPtr methodID, jvalue[] args) { JNI_CALL_METHOD( CallStaticBooleanMethodA, (jclass)clazz ); } + // Invokes a static method on a Java object, according to the specified <tt>methodID</tt>, optionally passing an array of arguments (<tt>args</tt>) to the method. + THREAD_SAFE CUSTOM static Int16 CallStaticShortMethod(IntPtr clazz, IntPtr methodID, jvalue[] args) { JNI_CALL_METHOD( CallStaticShortMethodA, (jclass)clazz ); } + // Invokes a static method on a Java object, according to the specified <tt>methodID</tt>, optionally passing an array of arguments (<tt>args</tt>) to the method. + THREAD_SAFE CUSTOM static Byte CallStaticByteMethod(IntPtr clazz, IntPtr methodID, jvalue[] args) { JNI_CALL_METHOD( CallStaticByteMethodA, (jclass)clazz ); } + // Invokes a static method on a Java object, according to the specified <tt>methodID</tt>, optionally passing an array of arguments (<tt>args</tt>) to the method. + THREAD_SAFE CUSTOM static Char CallStaticCharMethod(IntPtr clazz, IntPtr methodID, jvalue[] args) { JNI_CALL_METHOD( CallStaticCharMethodA, (jclass)clazz ); } + // Invokes a static method on a Java object, according to the specified <tt>methodID</tt>, optionally passing an array of arguments (<tt>args</tt>) to the method. + THREAD_SAFE CUSTOM static float CallStaticFloatMethod(IntPtr clazz, IntPtr methodID, jvalue[] args) { JNI_CALL_METHOD( CallStaticFloatMethodA, (jclass)clazz ); } + // Invokes a static method on a Java object, according to the specified <tt>methodID</tt>, optionally passing an array of arguments (<tt>args</tt>) to the method. + THREAD_SAFE CUSTOM static double CallStaticDoubleMethod(IntPtr clazz, IntPtr methodID, jvalue[] args) { JNI_CALL_METHOD( CallStaticDoubleMethodA, (jclass)clazz ); } + // Invokes a static method on a Java object, according to the specified <tt>methodID</tt>, optionally passing an array of arguments (<tt>args</tt>) to the method. + THREAD_SAFE CUSTOM static Int64 CallStaticLongMethod(IntPtr clazz, IntPtr methodID, jvalue[] args) { JNI_CALL_METHOD( CallStaticLongMethodA, (jclass)clazz ); } + // Invokes a static method on a Java object, according to the specified <tt>methodID</tt>, optionally passing an array of arguments (<tt>args</tt>) to the method. + THREAD_SAFE CUSTOM static void CallStaticVoidMethod(IntPtr clazz, IntPtr methodID, jvalue[] args) { JNI_CALL_VOID_METHOD( CallStaticVoidMethodA, (jclass)clazz ); } + + //--------------------------------------------- + + // This function returns the value of a static field of an object. + THREAD_SAFE CUSTOM static string GetStaticStringField(IntPtr clazz, IntPtr fieldID) { JNI_GET_JSTR_FIELD( GetStaticObjectField, (jclass)clazz ); } + // This function returns the value of a static field of an object. + THREAD_SAFE CUSTOM static IntPtr GetStaticObjectField(IntPtr clazz, IntPtr fieldID) { JNI_GET_FIELD( GetStaticObjectField, (jclass)clazz ); } + // This function returns the value of a static field of an object. + THREAD_SAFE CUSTOM static bool GetStaticBooleanField(IntPtr clazz, IntPtr fieldID) { JNI_GET_FIELD( GetStaticBooleanField, (jclass)clazz ); } + // This function returns the value of a static field of an object. + THREAD_SAFE CUSTOM static Byte GetStaticByteField(IntPtr clazz, IntPtr fieldID) { JNI_GET_FIELD( GetStaticByteField, (jclass)clazz ); } + // This function returns the value of a static field of an object. + THREAD_SAFE CUSTOM static Char GetStaticCharField(IntPtr clazz, IntPtr fieldID) { JNI_GET_FIELD( GetStaticCharField, (jclass)clazz ); } + // This function returns the value of a static field of an object. + THREAD_SAFE CUSTOM static Int16 GetStaticShortField(IntPtr clazz, IntPtr fieldID) { JNI_GET_FIELD( GetStaticShortField, (jclass)clazz ); } + // This function returns the value of a static field of an object. + THREAD_SAFE CUSTOM static Int32 GetStaticIntField(IntPtr clazz, IntPtr fieldID) { JNI_GET_FIELD( GetStaticIntField, (jclass)clazz ); } + // This function returns the value of a static field of an object. + THREAD_SAFE CUSTOM static Int64 GetStaticLongField(IntPtr clazz, IntPtr fieldID) { JNI_GET_FIELD( GetStaticLongField, (jclass)clazz ); } + // This function returns the value of a static field of an object. + THREAD_SAFE CUSTOM static float GetStaticFloatField(IntPtr clazz, IntPtr fieldID) { JNI_GET_FIELD( GetStaticFloatField, (jclass)clazz ); } + // This function returns the value of a static field of an object. + THREAD_SAFE CUSTOM static double GetStaticDoubleField(IntPtr clazz, IntPtr fieldID) { JNI_GET_FIELD( GetStaticDoubleField, (jclass)clazz ); } + + //--------------------------------------------- + + // This function ets the value of a static field of an object. + THREAD_SAFE CUSTOM static void SetStaticStringField(IntPtr clazz, IntPtr fieldID, string val) { JNI_PASS_VOID_ARGS( SetStaticObjectField, (jclass)clazz, (jfieldID)fieldID, jStringWrapper(val) ); } + // This function ets the value of a static field of an object. + THREAD_SAFE CUSTOM static void SetStaticObjectField(IntPtr clazz, IntPtr fieldID, IntPtr val) { JNI_SET_FIELD( SetStaticObjectField, (jclass)clazz, (jclass)val ); } + // This function ets the value of a static field of an object. + THREAD_SAFE CUSTOM static void SetStaticBooleanField(IntPtr clazz, IntPtr fieldID, bool val) { JNI_SET_FIELD( SetStaticBooleanField, (jclass)clazz, val ); } + // This function ets the value of a static field of an object. + THREAD_SAFE CUSTOM static void SetStaticByteField(IntPtr clazz, IntPtr fieldID, Byte val) { JNI_SET_FIELD( SetStaticByteField, (jclass)clazz, val ); } + // This function ets the value of a static field of an object. + THREAD_SAFE CUSTOM static void SetStaticCharField(IntPtr clazz, IntPtr fieldID, Char val) { JNI_SET_FIELD( SetStaticCharField, (jclass)clazz, val ); } + // This function ets the value of a static field of an object. + THREAD_SAFE CUSTOM static void SetStaticShortField(IntPtr clazz, IntPtr fieldID, Int16 val) { JNI_SET_FIELD( SetStaticShortField, (jclass)clazz, val ); } + // This function ets the value of a static field of an object. + THREAD_SAFE CUSTOM static void SetStaticIntField(IntPtr clazz, IntPtr fieldID, Int32 val) { JNI_SET_FIELD( SetStaticIntField, (jclass)clazz, val ); } + // This function ets the value of a static field of an object. + THREAD_SAFE CUSTOM static void SetStaticLongField(IntPtr clazz, IntPtr fieldID, Int64 val) { JNI_SET_FIELD( SetStaticLongField, (jclass)clazz, val ); } + // This function ets the value of a static field of an object. + THREAD_SAFE CUSTOM static void SetStaticFloatField(IntPtr clazz, IntPtr fieldID, float val) { JNI_SET_FIELD( SetStaticFloatField, (jclass)clazz, val ); } + // This function ets the value of a static field of an object. + THREAD_SAFE CUSTOM static void SetStaticDoubleField(IntPtr clazz, IntPtr fieldID, double val) { JNI_SET_FIELD( SetStaticDoubleField, (jclass)clazz, val ); } + + +//--------------------------------------- + + // Convert a managed array of System.Boolean to a Java array of <tt>boolean</tt>. + THREAD_SAFE CUSTOM static IntPtr ToBooleanArray(Boolean[] array) { JNI_NEW_ARRAY( Boolean, jboolean, jbooleanArray );} + // Convert a managed array of System.Byte to a Java array of <tt>byte</tt>. + THREAD_SAFE CUSTOM static IntPtr ToByteArray(Byte[] array) { JNI_NEW_ARRAY( Byte, jbyte, jbyteArray ); } + // Convert a managed array of System.Char to a Java array of <tt>char</tt>. + THREAD_SAFE CUSTOM static IntPtr ToCharArray(Char[] array) { JNI_NEW_ARRAY( Char, jchar, jcharArray ); } + // Convert a managed array of System.Int16 to a Java array of <tt>short</tt>. + THREAD_SAFE CUSTOM static IntPtr ToShortArray(Int16[] array) { JNI_NEW_ARRAY( Short, jshort, jshortArray ); } + // Convert a managed array of System.Int32 to a Java array of <tt>int</tt>. + THREAD_SAFE CUSTOM static IntPtr ToIntArray(Int32[] array) { JNI_NEW_ARRAY( Int, jint, jintArray ); } + // Convert a managed array of System.Int64 to a Java array of <tt>long</tt>. + THREAD_SAFE CUSTOM static IntPtr ToLongArray(Int64[] array) { JNI_NEW_ARRAY( Long, jlong, jlongArray ); } + // Convert a managed array of System.Single to a Java array of <tt>float</tt>. + THREAD_SAFE CUSTOM static IntPtr ToFloatArray(float[] array) { JNI_NEW_ARRAY( Float, jfloat, jfloatArray ); } + // Convert a managed array of System.Double to a Java array of <tt>double</tt>. + THREAD_SAFE CUSTOM static IntPtr ToDoubleArray(double[] array) { JNI_NEW_ARRAY( Double, jdouble, jdoubleArray ); } + // Convert a managed array of System.IntPtr, representing Java objects, to a Java array of <tt>java.lang.Object</tt>. + THREAD_SAFE CUSTOM static IntPtr ToObjectArray(IntPtr[] array) + { + #if UNITY_ANDROID + SCOPED_JNI(__FUNCTION__); + if (!jni_env) return 0; + int size = mono_array_length(array); + jclass obj_class = jni_env->FindClass("java/lang/Object"); + if (obj_class == 0 || jni_env->ExceptionCheck()) return SCRIPTING_NULL; + jobjectArray jni_array = jni_env->NewObjectArray(size, obj_class, 0); + if (jni_array == 0 || jni_env->ExceptionCheck()) + { + jni_env->DeleteLocalRef(obj_class); + return SCRIPTING_NULL; + } + for (int i = 0; i < size; ++i) + { + void* val = GetMonoArrayElement<void*>(array, i); + jni_env->SetObjectArrayElement(jni_array, i, (jobject)val); + jni_env->DeleteLocalRef((jobject) val); + if (jni_env->ExceptionCheck()) + { + jni_env->DeleteLocalRef(jni_array); + jni_env->DeleteLocalRef(obj_class); + return SCRIPTING_NULL; + } + } + jni_env->DeleteLocalRef(obj_class); + return jni_array; + #else + return 0; + #endif + } + + // Convert a Java array of <tt>boolean</tt> to a managed array of System.Boolean. + THREAD_SAFE CUSTOM static Boolean[] FromBooleanArray(IntPtr array) { JNI_GET_ARRAY( Boolean, jboolean, jbooleanArray, mono_get_boolean_class() ); } + // Convert a Java array of <tt>byte</tt> to a managed array of System.Byte. + THREAD_SAFE CUSTOM static Byte[] FromByteArray(IntPtr array) { JNI_GET_ARRAY( Byte, jbyte, jbyteArray, mono_get_byte_class() ); } + // Convert a Java array of <tt>char</tt> to a managed array of System.Char. + THREAD_SAFE CUSTOM static Char[] FromCharArray(IntPtr array) { JNI_GET_ARRAY( Char, jchar, jcharArray, mono_get_char_class() ); } + // Convert a Java array of <tt>short</tt> to a managed array of System.Int16. + THREAD_SAFE CUSTOM static Int16[] FromShortArray(IntPtr array) { JNI_GET_ARRAY( Short, jshort, jshortArray, mono_get_int16_class() ); } + // Convert a Java array of <tt>int</tt> to a managed array of System.Int32. + THREAD_SAFE CUSTOM static Int32[] FromIntArray(IntPtr array) { JNI_GET_ARRAY( Int, jint, jintArray, mono_get_int32_class() ); } + // Convert a Java array of <tt>long</tt> to a managed array of System.Int64. + THREAD_SAFE CUSTOM static Int64[] FromLongArray(IntPtr array) { JNI_GET_ARRAY( Long, jlong, jlongArray, mono_get_int64_class() ); } + // Convert a Java array of <tt>float</tt> to a managed array of System.Single. + THREAD_SAFE CUSTOM static float[] FromFloatArray(IntPtr array) { JNI_GET_ARRAY( Float, jfloat, jfloatArray, mono_get_single_class() ); } + // Convert a Java array of <tt>double</tt> to a managed array of System.Double. + THREAD_SAFE CUSTOM static double[] FromDoubleArray(IntPtr array) { JNI_GET_ARRAY( Double, jdouble, jdoubleArray, mono_get_double_class() ); } + // Convert a Java array of <tt>java.lang.Object</tt> to a managed array of System.IntPtr, representing Java objects. + THREAD_SAFE CUSTOM static IntPtr[] FromObjectArray(IntPtr array) + { + #if UNITY_ANDROID + SCOPED_JNI(__FUNCTION__); + if (!jni_env) return 0; + jsize length = jni_env->GetArrayLength((jarray)array); + if (jni_env->ExceptionCheck()) return SCRIPTING_NULL; + MonoClass* clazz = mono_class_from_name (mono_get_corlib (), "System", "IntPtr"); + MonoArray* csarray = mono_array_new(mono_domain_get(), clazz, length); + for (int i = 0; i < length; ++i) + { + jobject obj = jni_env->GetObjectArrayElement((jobjectArray)array, i); + if (jni_env->ExceptionCheck()) return SCRIPTING_NULL; + Scripting::SetScriptingArrayElement<jobject>(csarray, i, obj); + } + return csarray; + #else + return SCRIPTING_NULL; + #endif + } + + // Returns the number of elements in the array. + THREAD_SAFE CUSTOM static int GetArrayLength(IntPtr array) { JNI_PASS_RETV_ARGS( GetArrayLength, (jarray) array); } + + // Construct a new primitive array object. + THREAD_SAFE CUSTOM static IntPtr NewBooleanArray(int size) { JNI_PASS_RETV_ARGS( NewBooleanArray, (jsize)size);} + // Construct a new primitive array object. + THREAD_SAFE CUSTOM static IntPtr NewByteArray(int size) { JNI_PASS_RETV_ARGS( NewByteArray, (jsize)size); } + // Construct a new primitive array object. + THREAD_SAFE CUSTOM static IntPtr NewCharArray(int size) { JNI_PASS_RETV_ARGS( NewCharArray, (jsize)size); } + // Construct a new primitive array object. + THREAD_SAFE CUSTOM static IntPtr NewShortArray(int size) { JNI_PASS_RETV_ARGS( NewShortArray, (jsize)size); } + // Construct a new primitive array object. + THREAD_SAFE CUSTOM static IntPtr NewIntArray(int size) { JNI_PASS_RETV_ARGS( NewIntArray, (jsize)size); } + // Construct a new primitive array object. + THREAD_SAFE CUSTOM static IntPtr NewLongArray(int size) { JNI_PASS_RETV_ARGS( NewLongArray, (jsize)size); } + // Construct a new primitive array object. + THREAD_SAFE CUSTOM static IntPtr NewFloatArray(int size) { JNI_PASS_RETV_ARGS( NewFloatArray, (jsize)size); } + // Construct a new primitive array object. + THREAD_SAFE CUSTOM static IntPtr NewDoubleArray(int size) { JNI_PASS_RETV_ARGS( NewDoubleArray, (jsize)size); } + // Constructs a new array holding objects in class <tt>clazz</tt>. All elements are initially set to <tt>obj</tt>. + THREAD_SAFE CUSTOM static IntPtr NewObjectArray(int size, IntPtr clazz, IntPtr obj) { JNI_PASS_RETV_ARGS( NewObjectArray, (jsize)size, (jclass)clazz, (jobject) obj); } + + // Returns the value of one element of a primitive array. + THREAD_SAFE CUSTOM static bool GetBooleanArrayElement(IntPtr array, int index) { JNI_GET_ARRAY_ELEMENT( Boolean, jboolean, jbooleanArray ); } + // Returns the value of one element of a primitive array. + THREAD_SAFE CUSTOM static Byte GetByteArrayElement(IntPtr array, int index) { JNI_GET_ARRAY_ELEMENT( Byte, jbyte, jbyteArray ); } + // Returns the value of one element of a primitive array. + THREAD_SAFE CUSTOM static Char GetCharArrayElement(IntPtr array, int index) { JNI_GET_ARRAY_ELEMENT( Char, jchar, jcharArray ); } + // Returns the value of one element of a primitive array. + THREAD_SAFE CUSTOM static Int16 GetShortArrayElement(IntPtr array, int index) { JNI_GET_ARRAY_ELEMENT( Short, jshort, jshortArray ); } + // Returns the value of one element of a primitive array. + THREAD_SAFE CUSTOM static Int32 GetIntArrayElement(IntPtr array, int index) { JNI_GET_ARRAY_ELEMENT( Int, jint, jintArray ); } + // Returns the value of one element of a primitive array. + THREAD_SAFE CUSTOM static Int64 GetLongArrayElement(IntPtr array, int index) { JNI_GET_ARRAY_ELEMENT( Long, jlong, jlongArray ); } + // Returns the value of one element of a primitive array. + THREAD_SAFE CUSTOM static float GetFloatArrayElement(IntPtr array, int index) { JNI_GET_ARRAY_ELEMENT( Float, jfloat, jfloatArray ); } + // Returns the value of one element of a primitive array. + THREAD_SAFE CUSTOM static double GetDoubleArrayElement(IntPtr array, int index) { JNI_GET_ARRAY_ELEMENT( Double, jdouble, jdoubleArray ); } + // Returns an element of an <tt>Object</tt> array. + THREAD_SAFE CUSTOM static IntPtr GetObjectArrayElement(IntPtr array, int index) { JNI_PASS_RETV_ARGS( GetObjectArrayElement, (jobjectArray)array, (jsize)index); } + + // Sets the value of one element in a primitive array. + THREAD_SAFE CUSTOM static void SetBooleanArrayElement(IntPtr array, int index, byte val) { JNI_SET_ARRAY_ELEMENT( Boolean, jboolean, jbooleanArray ); } + // Sets the value of one element in a primitive array. + THREAD_SAFE CUSTOM static void SetByteArrayElement(IntPtr array, int index, sbyte val) { JNI_SET_ARRAY_ELEMENT( Byte, jbyte, jbyteArray ); } + // Sets the value of one element in a primitive array. + THREAD_SAFE CUSTOM static void SetCharArrayElement(IntPtr array, int index, Char val) { JNI_SET_ARRAY_ELEMENT( Char, jchar, jcharArray ); } + // Sets the value of one element in a primitive array. + THREAD_SAFE CUSTOM static void SetShortArrayElement(IntPtr array, int index, Int16 val) { JNI_SET_ARRAY_ELEMENT( Short, jshort, jshortArray ); } + // Sets the value of one element in a primitive array. + THREAD_SAFE CUSTOM static void SetIntArrayElement(IntPtr array, int index, Int32 val) { JNI_SET_ARRAY_ELEMENT( Int, jint, jintArray ); } + // Sets the value of one element in a primitive array. + THREAD_SAFE CUSTOM static void SetLongArrayElement(IntPtr array, int index, Int64 val) { JNI_SET_ARRAY_ELEMENT( Long, jlong, jlongArray ); } + // Sets the value of one element in a primitive array. + THREAD_SAFE CUSTOM static void SetFloatArrayElement(IntPtr array, int index, float val) { JNI_SET_ARRAY_ELEMENT( Float, jfloat, jfloatArray ); } + // Sets the value of one element in a primitive array. + THREAD_SAFE CUSTOM static void SetDoubleArrayElement(IntPtr array, int index, double val) { JNI_SET_ARRAY_ELEMENT( Double, jdouble, jdoubleArray ); } + // Sets an element of an <tt>Object</tt> array. + THREAD_SAFE CUSTOM static void SetObjectArrayElement(IntPtr array, int index, IntPtr obj) { JNI_PASS_VOID_ARGS( SetObjectArrayElement, (jobjectArray)array, (jsize)index, (jobject)obj); } +END + + +CSRAW +} +#endif |