From 4c105ee3dee8cd7fad080d8869a2a3651296298e Mon Sep 17 00:00:00 2001 From: johnche Date: Fri, 8 Nov 2024 15:33:54 +0800 Subject: [PATCH] =?UTF-8?q?[unity]=E6=99=AE=E9=80=9A=E7=89=88=E6=9C=AC?= =?UTF-8?q?=E7=94=A8papi=E5=AE=9E=E7=8E=B0=E7=9A=84=E5=8F=AF=E8=A1=8C?= =?UTF-8?q?=E6=80=A7=E9=AA=8C=E8=AF=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../core/upm/Runtime/Src/IL2Cpp/JsEnv.cs | 43 +++++ .../Runtime/Src/IL2Cpp/Native/NativeAPI.cs | 181 ++++++++++++++++++ 2 files changed, 224 insertions(+) diff --git a/unity/Assets/core/upm/Runtime/Src/IL2Cpp/JsEnv.cs b/unity/Assets/core/upm/Runtime/Src/IL2Cpp/JsEnv.cs index 6b45d1bbc2..d9cc6b3638 100644 --- a/unity/Assets/core/upm/Runtime/Src/IL2Cpp/JsEnv.cs +++ b/unity/Assets/core/upm/Runtime/Src/IL2Cpp/JsEnv.cs @@ -11,6 +11,7 @@ using System; using System.Collections.Generic; using System.Reflection; +using System.Runtime.InteropServices; #if CSHARP_7_3_OR_NEWER using System.Threading.Tasks; #endif @@ -149,6 +150,48 @@ public JsEnv(ILoader loader, int debugPort = -1) } if (loader is IBuiltinLoadedListener) (loader as IBuiltinLoadedListener).OnBuiltinLoaded(this); + + PuertsIl2cpp.pesapi_ffi ffi = Marshal.PtrToStructure(apis); + var scope = ffi.open_scope(nativePesapiEnv); + var env = ffi.get_env_from_ref(nativePesapiEnv); + var func = ffi.create_function(env, FooImpl, IntPtr.Zero); + var global = ffi.global(env); + ffi.set_property(env, global, "CSharpFoo", func); + ffi.close_scope(scope); + } + + static IntPtr storeCallback = IntPtr.Zero; + + [PuertsIl2cpp.MonoPInvokeCallback(typeof(PuertsIl2cpp.pesapi_callback))] + static void FooImpl(IntPtr apis, IntPtr info) + { + PuertsIl2cpp.pesapi_ffi ffi = Marshal.PtrToStructure(apis); + var env = ffi.get_env(info); + + IntPtr p0 = ffi.get_arg(info, 0); + if (ffi.is_function(env, p0)) + { + if (storeCallback == IntPtr.Zero) + { + storeCallback = ffi.create_value_ref(env, p0, 0); + } + return; + } + + if (storeCallback != IntPtr.Zero) + { + IntPtr func = ffi.get_value_from_ref(env, storeCallback); + IntPtr[] argv = new IntPtr[2] {p0, ffi.get_arg(info, 1)}; + IntPtr res = ffi.call_function(env, func, IntPtr.Zero, 2, argv); + int sum = ffi.get_value_int32(env, res); + UnityEngine.Debug.Log(string.Format("callback result = {0}", sum)); + return; + } + + int x = ffi.get_value_int32(env, p0); + int y = ffi.get_value_int32(env, ffi.get_arg(info, 1)); + UnityEngine.Debug.Log(string.Format("CSharpFoo called, x = {0}, y = {1}", x, y)); + ffi.add_return(info, ffi.create_int32(env, x + y)); } public void AddRegisterInfoGetter(Type type, Func getter) diff --git a/unity/Assets/core/upm/Runtime/Src/IL2Cpp/Native/NativeAPI.cs b/unity/Assets/core/upm/Runtime/Src/IL2Cpp/Native/NativeAPI.cs index 0c485a206d..ee3ecc0c6b 100644 --- a/unity/Assets/core/upm/Runtime/Src/IL2Cpp/Native/NativeAPI.cs +++ b/unity/Assets/core/upm/Runtime/Src/IL2Cpp/Native/NativeAPI.cs @@ -244,6 +244,187 @@ public static void SetLogCallback(LogCallback log) } } } + + public delegate void pesapi_callback(IntPtr apis, IntPtr info); + + public delegate IntPtr pesapi_create_null_func(IntPtr env); + public delegate IntPtr pesapi_create_undefined_func(IntPtr env); + public delegate IntPtr pesapi_create_boolean_func(IntPtr env, bool value); + public delegate IntPtr pesapi_create_int32_func(IntPtr env, int value); + public delegate IntPtr pesapi_create_uint32_func(IntPtr env, uint value); + public delegate IntPtr pesapi_create_int64_func(IntPtr env, long value); + public delegate IntPtr pesapi_create_uint64_func(IntPtr env, ulong value); + public delegate IntPtr pesapi_create_double_func(IntPtr env, double value); + public delegate IntPtr pesapi_create_string_utf8_func(IntPtr env, string str, UIntPtr length); + public delegate IntPtr pesapi_create_binary_func(IntPtr env, IntPtr str, UIntPtr length); + public delegate IntPtr pesapi_create_array_func(IntPtr env); + public delegate IntPtr pesapi_create_object_func(IntPtr env); + public delegate IntPtr pesapi_create_function_func(IntPtr env, pesapi_callback native_impl, IntPtr data); + public delegate IntPtr pesapi_create_class_func(IntPtr env, IntPtr type_id); + + public delegate bool pesapi_get_value_bool_func(IntPtr env, IntPtr value); + public delegate int pesapi_get_value_int32_func(IntPtr env, IntPtr value); + public delegate uint pesapi_get_value_uint32_func(IntPtr env, IntPtr value); + public delegate long pesapi_get_value_int64_func(IntPtr env, IntPtr value); + public delegate ulong pesapi_get_value_uint64_func(IntPtr env, IntPtr value); + public delegate double pesapi_get_value_double_func(IntPtr env, IntPtr value); + public delegate IntPtr pesapi_get_value_string_utf8_func(IntPtr env, IntPtr value, IntPtr buf, ref UIntPtr bufsize); + public delegate IntPtr pesapi_get_value_binary_func(IntPtr env, IntPtr pvalue, ref UIntPtr bufsize); + public delegate uint pesapi_get_array_length_func(IntPtr env, IntPtr value); + + public delegate bool pesapi_is_null_func(IntPtr env, IntPtr value); + public delegate bool pesapi_is_undefined_func(IntPtr env, IntPtr value); + public delegate bool pesapi_is_boolean_func(IntPtr env, IntPtr value); + public delegate bool pesapi_is_int32_func(IntPtr env, IntPtr value); + public delegate bool pesapi_is_uint32_func(IntPtr env, IntPtr value); + public delegate bool pesapi_is_int64_func(IntPtr env, IntPtr value); + public delegate bool pesapi_is_uint64_func(IntPtr env, IntPtr value); + public delegate bool pesapi_is_double_func(IntPtr env, IntPtr value); + public delegate bool pesapi_is_string_func(IntPtr env, IntPtr value); + public delegate bool pesapi_is_object_func(IntPtr env, IntPtr value); + public delegate bool pesapi_is_function_func(IntPtr env, IntPtr value); + public delegate bool pesapi_is_binary_func(IntPtr env, IntPtr value); + public delegate bool pesapi_is_array_func(IntPtr env, IntPtr value); + + public delegate IntPtr pesapi_native_object_to_value_func(IntPtr env, IntPtr type_id, IntPtr object_ptr, bool call_finalize); + public delegate IntPtr pesapi_get_native_object_ptr_func(IntPtr env, IntPtr value); + public delegate IntPtr pesapi_get_native_object_typeid_func(IntPtr env, IntPtr value); + public delegate bool pesapi_is_instance_of_func(IntPtr env, IntPtr type_id, IntPtr value); + + public delegate IntPtr pesapi_boxing_func(IntPtr env, IntPtr value); + public delegate IntPtr pesapi_unboxing_func(IntPtr env, IntPtr value); + public delegate void pesapi_update_boxed_value_func(IntPtr env, IntPtr boxed_value, IntPtr value); + public delegate bool pesapi_is_boxed_value_func(IntPtr env, IntPtr value); + + public delegate int pesapi_get_args_len_func(IntPtr info); + public delegate IntPtr pesapi_get_arg_func(IntPtr info, int index); + public delegate IntPtr pesapi_get_env_func(IntPtr info); + public delegate IntPtr pesapi_get_this_func(IntPtr info); + public delegate IntPtr pesapi_get_holder_func(IntPtr info); + public delegate IntPtr pesapi_get_userdata_func(IntPtr info); + public delegate void pesapi_add_return_func(IntPtr info, IntPtr value); + public delegate void pesapi_throw_by_string_func(IntPtr pinfo, string msg); + + public delegate IntPtr pesapi_create_env_ref_func(IntPtr env); + public delegate bool pesapi_env_ref_is_valid_func(IntPtr env); + public delegate IntPtr pesapi_get_env_from_ref_func(IntPtr env_ref); + public delegate IntPtr pesapi_duplicate_env_ref_func(IntPtr env_ref); + public delegate void pesapi_release_env_ref_func(IntPtr env_ref); + public delegate IntPtr pesapi_open_scope_func(IntPtr env_ref); + public delegate IntPtr pesapi_open_scope_placement_func(IntPtr env_ref, IntPtr memory); + public delegate bool pesapi_has_caught_func(IntPtr scope); + public delegate IntPtr pesapi_get_exception_as_string_func(IntPtr scope, bool with_stack); + public delegate void pesapi_close_scope_func(IntPtr scope); + public delegate void pesapi_close_scope_placement_func(IntPtr scope); + + public delegate IntPtr pesapi_create_value_ref_func(IntPtr env, IntPtr value, uint internal_field_count); + public delegate IntPtr pesapi_duplicate_value_ref_func(IntPtr value_ref); + public delegate void pesapi_release_value_ref_func(IntPtr value_ref); + public delegate IntPtr pesapi_get_value_from_ref_func(IntPtr env, IntPtr value_ref); + public delegate void pesapi_set_ref_weak_func(IntPtr env, IntPtr value_ref); + public delegate bool pesapi_set_owner_func(IntPtr env, IntPtr value, IntPtr owner); + public delegate IntPtr pesapi_get_ref_associated_env_func(IntPtr value_ref); + public delegate IntPtr pesapi_get_ref_internal_fields_func(IntPtr value_ref, ref uint pinternal_field_count); + + public delegate IntPtr pesapi_get_property_func(IntPtr env, IntPtr objectPtr, string key); + public delegate void pesapi_set_property_func(IntPtr env, IntPtr objectPtr, string key, IntPtr value); + public delegate bool pesapi_get_private_func(IntPtr env, IntPtr objectPtr, out IntPtr outPtr); + public delegate bool pesapi_set_private_func(IntPtr env, IntPtr objectPtr, IntPtr ptr); + public delegate IntPtr pesapi_get_property_uint32_func(IntPtr env, IntPtr objectPtr, uint key); + public delegate void pesapi_set_property_uint32_func(IntPtr env, IntPtr objectPtr, uint key, IntPtr value); + + public delegate IntPtr pesapi_call_function_func(IntPtr env, IntPtr func, IntPtr this_object, int argc, IntPtr[] argv); + public delegate IntPtr pesapi_eval_func(IntPtr env, IntPtr code, UIntPtr code_size, string path); + public delegate IntPtr pesapi_global_func(IntPtr env); + public delegate IntPtr pesapi_get_env_private_func(IntPtr env); + public delegate void pesapi_set_env_private_func(IntPtr env, IntPtr ptr); + + [StructLayout(LayoutKind.Sequential)] + public struct pesapi_ffi + { + public pesapi_create_null_func create_null; + public pesapi_create_undefined_func create_undefined; + public pesapi_create_boolean_func create_boolean; + public pesapi_create_int32_func create_int32; + public pesapi_create_uint32_func create_uint32; + public pesapi_create_int64_func create_int64; + public pesapi_create_uint64_func create_uint64; + public pesapi_create_double_func create_double; + public pesapi_create_string_utf8_func create_string_utf8; + public pesapi_create_binary_func create_binary; + public pesapi_create_array_func create_array; + public pesapi_create_object_func create_object; + public pesapi_create_function_func create_function; + public pesapi_create_class_func create_class; + public pesapi_get_value_bool_func get_value_bool; + public pesapi_get_value_int32_func get_value_int32; + public pesapi_get_value_uint32_func get_value_uint32; + public pesapi_get_value_int64_func get_value_int64; + public pesapi_get_value_uint64_func get_value_uint64; + public pesapi_get_value_double_func get_value_double; + public pesapi_get_value_string_utf8_func get_value_string_utf8; + public pesapi_get_value_binary_func get_value_binary; + public pesapi_get_array_length_func get_array_length; + public pesapi_is_null_func is_null; + public pesapi_is_undefined_func is_undefined; + public pesapi_is_boolean_func is_boolean; + public pesapi_is_int32_func is_int32; + public pesapi_is_uint32_func is_uint32; + public pesapi_is_int64_func is_int64; + public pesapi_is_uint64_func is_uint64; + public pesapi_is_double_func is_double; + public pesapi_is_string_func is_string; + public pesapi_is_object_func is_object; + public pesapi_is_function_func is_function; + public pesapi_is_binary_func is_binary; + public pesapi_is_array_func is_array; + public pesapi_native_object_to_value_func native_object_to_value; + public pesapi_get_native_object_ptr_func get_native_object_ptr; + public pesapi_get_native_object_typeid_func get_native_object_typeid; + public pesapi_is_instance_of_func is_instance_of; + public pesapi_boxing_func boxing; + public pesapi_unboxing_func unboxing; + public pesapi_update_boxed_value_func update_boxed_value; + public pesapi_is_boxed_value_func is_boxed_value; + public pesapi_get_args_len_func get_args_len; + public pesapi_get_arg_func get_arg; + public pesapi_get_env_func get_env; + public pesapi_get_this_func get_this; + public pesapi_get_holder_func get_holder; + public pesapi_get_userdata_func get_userdata; + public pesapi_add_return_func add_return; + public pesapi_throw_by_string_func throw_by_string; + public pesapi_create_env_ref_func create_env_ref; + public pesapi_env_ref_is_valid_func env_ref_is_valid; + public pesapi_get_env_from_ref_func get_env_from_ref; + public pesapi_duplicate_env_ref_func duplicate_env_ref; + public pesapi_release_env_ref_func release_env_ref; + public pesapi_open_scope_func open_scope; + public pesapi_open_scope_placement_func open_scope_placement; + public pesapi_has_caught_func has_caught; + public pesapi_get_exception_as_string_func get_exception_as_string; + public pesapi_close_scope_func close_scope; + public pesapi_close_scope_placement_func close_scope_placement; + public pesapi_create_value_ref_func create_value_ref; + public pesapi_duplicate_value_ref_func duplicate_value_ref; + public pesapi_release_value_ref_func release_value_ref; + public pesapi_get_value_from_ref_func get_value_from_ref; + public pesapi_set_ref_weak_func set_ref_weak; + public pesapi_set_owner_func set_owner; + public pesapi_get_ref_associated_env_func get_ref_associated_env; + public pesapi_get_ref_internal_fields_func get_ref_internal_fields; + public pesapi_get_property_func get_property; + public pesapi_set_property_func set_property; + public pesapi_get_private_func get_private; + public pesapi_set_private_func set_private; + public pesapi_get_property_uint32_func get_property_uint32; + public pesapi_set_property_uint32_func set_property_uint32; + public pesapi_call_function_func call_function; + public pesapi_eval_func eval; + public pesapi_global_func global; + public pesapi_get_env_private_func get_env_private; + public pesapi_set_env_private_func set_env_private; + } } #endif