diff options
Diffstat (limited to 'modules/mono')
-rw-r--r-- | modules/mono/SCsub | 5 | ||||
-rw-r--r-- | modules/mono/csharp_script.cpp | 2 | ||||
-rw-r--r-- | modules/mono/editor/godotsharp_builds.cpp | 2 | ||||
-rw-r--r-- | modules/mono/glue/cs_files/Basis.cs | 77 | ||||
-rw-r--r-- | modules/mono/glue/cs_files/Quat.cs | 4 | ||||
-rw-r--r-- | modules/mono/glue/cs_files/Transform.cs | 8 | ||||
-rw-r--r-- | modules/mono/mono_gd/gd_mono.cpp | 34 | ||||
-rw-r--r-- | modules/mono/mono_gd/gd_mono.h | 2 | ||||
-rw-r--r-- | modules/mono/mono_gd/gd_mono_assembly.cpp | 97 | ||||
-rw-r--r-- | modules/mono/mono_gd/gd_mono_assembly.h | 8 | ||||
-rw-r--r-- | modules/mono/mono_gd/gd_mono_field.cpp | 4 | ||||
-rw-r--r-- | modules/mono/mono_gd/gd_mono_marshal.cpp | 55 | ||||
-rw-r--r-- | modules/mono/mono_gd/gd_mono_marshal.h | 19 |
13 files changed, 188 insertions, 129 deletions
diff --git a/modules/mono/SCsub b/modules/mono/SCsub index 0af2056c5c..caf4fdb3ca 100644 --- a/modules/mono/SCsub +++ b/modules/mono/SCsub @@ -2,9 +2,10 @@ Import('env') +from compat import byte_to_str def make_cs_files_header(src, dst): - with open(dst, 'wb') as header: + with open(dst, 'w') as header: header.write('/* This is an automatically generated file; DO NOT EDIT! OK THX */\n') header.write('#ifndef _CS_FILES_DATA_H\n') header.write('#define _CS_FILES_DATA_H\n\n') @@ -26,7 +27,7 @@ def make_cs_files_header(src, dst): for i, buf_idx in enumerate(range(len(buf))): if i > 0: header.write(', ') - header.write(str(ord(buf[buf_idx]))) + header.write(byte_to_str(buf[buf_idx])) inserted_files += '\tr_files.insert(\"' + file + '\", ' \ 'CompressedFile(_cs_' + name + '_compressed_size, ' \ '_cs_' + name + '_uncompressed_size, ' \ diff --git a/modules/mono/csharp_script.cpp b/modules/mono/csharp_script.cpp index 7de90dfbc3..fe78ce423c 100644 --- a/modules/mono/csharp_script.cpp +++ b/modules/mono/csharp_script.cpp @@ -782,7 +782,7 @@ bool CSharpInstance::set(const StringName &p_name, const Variant &p_value) { if (method) { MonoObject *ret = method->invoke(mono_object, args); - if (ret && UNBOX_BOOLEAN(ret)) + if (ret && GDMonoMarshal::unbox<MonoBoolean>(ret) == true) return true; } diff --git a/modules/mono/editor/godotsharp_builds.cpp b/modules/mono/editor/godotsharp_builds.cpp index 7b80e26645..1bad8a3f85 100644 --- a/modules/mono/editor/godotsharp_builds.cpp +++ b/modules/mono/editor/godotsharp_builds.cpp @@ -59,7 +59,7 @@ String _find_build_engine_on_unix(const String &p_name) { "/opt/novell/mono/bin/" }; - for (int i = 0; i < sizeof(locations) / sizeof(char); i++) { + for (int i = 0; i < sizeof(locations) / sizeof(const char *); i++) { String location = locations[i]; if (FileAccess::exists(location + p_name)) { diff --git a/modules/mono/glue/cs_files/Basis.cs b/modules/mono/glue/cs_files/Basis.cs index 6a73ebd554..c50e783349 100644 --- a/modules/mono/glue/cs_files/Basis.cs +++ b/modules/mono/glue/cs_files/Basis.cs @@ -160,26 +160,29 @@ namespace Godot Basis m = this.orthonormalized(); Vector3 euler; + euler.z = 0.0f; - euler.y = Mathf.asin(m.x[2]); + float mxy = m.y[2]; - if (euler.y < Mathf.PI * 0.5f) + + if (mxy < 1.0f) { - if (euler.y > -Mathf.PI * 0.5f) + if (mxy > -1.0f) { - euler.x = Mathf.atan2(-m.y[2], m.z[2]); - euler.z = Mathf.atan2(-m.x[1], m.x[0]); + euler.x = Mathf.asin(-mxy); + euler.y = Mathf.atan2(m.x[2], m.z[2]); + euler.z = Mathf.atan2(m.y[0], m.y[1]); } else { - euler.z = 0.0f; - euler.x = euler.z - Mathf.atan2(m.y[0], m.y[1]); + euler.x = Mathf.PI * 0.5f; + euler.y = -Mathf.atan2(-m.x[1], m.x[0]); } } else { - euler.z = 0f; - euler.x = Mathf.atan2(m.x[1], m.y[1]) - euler.z; + euler.x = -Mathf.PI * 0.5f; + euler.y = -Mathf.atan2(m.x[1], m.x[0]); } return euler; @@ -273,7 +276,7 @@ namespace Godot public Basis rotated(Vector3 axis, float phi) { - return this * new Basis(axis, phi); + return new Basis(axis, phi) * this; } public Basis scaled(Vector3 scale) @@ -281,13 +284,13 @@ namespace Godot Basis m = this; m[0, 0] *= scale.x; - m[1, 0] *= scale.x; - m[2, 0] *= scale.x; - m[0, 1] *= scale.y; + m[0, 1] *= scale.x; + m[0, 2] *= scale.x; + m[1, 0] *= scale.y; m[1, 1] *= scale.y; - m[2, 1] *= scale.y; - m[0, 2] *= scale.z; - m[1, 2] *= scale.z; + m[1, 2] *= scale.y; + m[2, 0] *= scale.z; + m[2, 1] *= scale.z; m[2, 2] *= scale.z; return m; @@ -347,6 +350,48 @@ namespace Godot ); } + public Quat Quat() { + float trace = x[0] + y[1] + z[2]; + + if (trace > 0.0f) { + float s = Mathf.sqrt(trace + 1.0f) * 2f; + float inv_s = 1f / s; + return new Quat( + (z[1] - y[2]) * inv_s, + (x[2] - z[0]) * inv_s, + (y[0] - x[1]) * inv_s, + s * 0.25f + ); + } else if (x[0] > y[1] && x[0] > z[2]) { + float s = Mathf.sqrt(x[0] - y[1] - z[2] + 1.0f) * 2f; + float inv_s = 1f / s; + return new Quat( + s * 0.25f, + (x[1] + y[0]) * inv_s, + (x[2] + z[0]) * inv_s, + (z[1] - y[2]) * inv_s + ); + } else if (y[1] > z[2]) { + float s = Mathf.sqrt(-x[0] + y[1] - z[2] + 1.0f) * 2f; + float inv_s = 1f / s; + return new Quat( + (x[1] + y[0]) * inv_s, + s * 0.25f, + (y[2] + z[1]) * inv_s, + (x[2] - z[0]) * inv_s + ); + } else { + float s = Mathf.sqrt(-x[0] - y[1] + z[2] + 1.0f) * 2f; + float inv_s = 1f / s; + return new Quat( + (x[2] + z[0]) * inv_s, + (y[2] + z[1]) * inv_s, + s * 0.25f, + (y[0] - x[1]) * inv_s + ); + } + } + public Basis(Quat quat) { float s = 2.0f / quat.length_squared(); diff --git a/modules/mono/glue/cs_files/Quat.cs b/modules/mono/glue/cs_files/Quat.cs index 6345239f47..9b4b7fb297 100644 --- a/modules/mono/glue/cs_files/Quat.cs +++ b/modules/mono/glue/cs_files/Quat.cs @@ -201,12 +201,12 @@ namespace Godot } else { - float s = Mathf.sin(-angle * 0.5f) / d; + float s = Mathf.sin(angle * 0.5f) / d; x = axis.x * s; y = axis.y * s; z = axis.z * s; - w = Mathf.cos(-angle * 0.5f); + w = Mathf.cos(angle * 0.5f); } } diff --git a/modules/mono/glue/cs_files/Transform.cs b/modules/mono/glue/cs_files/Transform.cs index 2010f0b3af..74271e758b 100644 --- a/modules/mono/glue/cs_files/Transform.cs +++ b/modules/mono/glue/cs_files/Transform.cs @@ -35,7 +35,7 @@ namespace Godot public Transform rotated(Vector3 axis, float phi) { - return this * new Transform(new Basis(axis, phi), new Vector3()); + return new Transform(new Basis(axis, phi), new Vector3()) * this; } public Transform scaled(Vector3 scale) @@ -104,6 +104,12 @@ namespace Godot this.origin = origin; } + public Transform(Quat quat, Vector3 origin) + { + this.basis = new Basis(quat); + this.origin = origin; + } + public Transform(Basis basis, Vector3 origin) { this.basis = basis; diff --git a/modules/mono/mono_gd/gd_mono.cpp b/modules/mono/mono_gd/gd_mono.cpp index d0b5b12d4b..2c88832998 100644 --- a/modules/mono/mono_gd/gd_mono.cpp +++ b/modules/mono/mono_gd/gd_mono.cpp @@ -266,6 +266,13 @@ void GDMono::add_assembly(uint32_t p_domain_id, GDMonoAssembly *p_assembly) { assemblies[p_domain_id][p_assembly->get_name()] = p_assembly; } +GDMonoAssembly **GDMono::get_loaded_assembly(const String &p_name) { + + MonoDomain *domain = mono_domain_get(); + uint32_t domain_id = domain ? mono_domain_get_id(domain) : 0; + return assemblies[domain_id].getptr(p_name); +} + bool GDMono::_load_assembly(const String &p_name, GDMonoAssembly **r_assembly) { CRASH_COND(!r_assembly); @@ -278,34 +285,17 @@ bool GDMono::_load_assembly(const String &p_name, GDMonoAssembly **r_assembly) { MonoAssembly *assembly = mono_assembly_load_full(aname, NULL, &status, false); mono_assembly_name_free(aname); - if (!assembly) - return false; + ERR_FAIL_NULL_V(assembly, false); uint32_t domain_id = mono_domain_get_id(mono_domain_get()); GDMonoAssembly **stored_assembly = assemblies[domain_id].getptr(p_name); - if (stored_assembly) { - // Loaded by our preload hook (status is not initialized when returning from a preload hook) - ERR_FAIL_COND_V((*stored_assembly)->get_assembly() != assembly, false); - *r_assembly = *stored_assembly; - } else { - ERR_FAIL_COND_V(status != MONO_IMAGE_OK, false); - - MonoImage *assembly_image = mono_assembly_get_image(assembly); - ERR_FAIL_NULL_V(assembly_image, false); - - const char *path = mono_image_get_filename(assembly_image); - - *r_assembly = memnew(GDMonoAssembly(p_name, path)); - Error error = (*r_assembly)->wrapper_for_image(assembly_image); + ERR_FAIL_COND_V(status != MONO_IMAGE_OK, false); + ERR_FAIL_COND_V(stored_assembly == NULL, false); - if (error != OK) { - memdelete(*r_assembly); - *r_assembly = NULL; - ERR_FAIL_V(false); - } - } + ERR_FAIL_COND_V((*stored_assembly)->get_assembly() != assembly, false); + *r_assembly = *stored_assembly; if (OS::get_singleton()->is_stdout_verbose()) OS::get_singleton()->print(String("Mono: Assembly " + p_name + " loaded from path: " + (*r_assembly)->get_path() + "\n").utf8()); diff --git a/modules/mono/mono_gd/gd_mono.h b/modules/mono/mono_gd/gd_mono.h index ab96d575e6..b188c0730a 100644 --- a/modules/mono/mono_gd/gd_mono.h +++ b/modules/mono/mono_gd/gd_mono.h @@ -122,7 +122,9 @@ public: static GDMono *get_singleton() { return singleton; } + // Do not use these, unless you know what you're doing void add_assembly(uint32_t p_domain_id, GDMonoAssembly *p_assembly); + GDMonoAssembly **get_loaded_assembly(const String &p_name); _FORCE_INLINE_ bool is_runtime_initialized() const { return runtime_initialized; } _FORCE_INLINE_ bool is_finalizing_scripts_domain() const { return finalizing_scripts_domain; } diff --git a/modules/mono/mono_gd/gd_mono_assembly.cpp b/modules/mono/mono_gd/gd_mono_assembly.cpp index a98537b9e1..4b370295f3 100644 --- a/modules/mono/mono_gd/gd_mono_assembly.cpp +++ b/modules/mono/mono_gd/gd_mono_assembly.cpp @@ -39,28 +39,60 @@ #include "../godotsharp_dirs.h" #include "gd_mono_class.h" -MonoAssembly *gdmono_load_assembly_from(const String &p_name, const String &p_path) { +bool GDMonoAssembly::no_search = false; +Vector<String> GDMonoAssembly::search_dirs; - MonoDomain *domain = mono_domain_get(); +MonoAssembly *GDMonoAssembly::_search_hook(MonoAssemblyName *aname, void *user_data) { - GDMonoAssembly *assembly = memnew(GDMonoAssembly(p_name, p_path)); - Error err = assembly->load(domain); - ERR_FAIL_COND_V(err != OK, NULL); + (void)user_data; // UNUSED - GDMono::get_singleton()->add_assembly(mono_domain_get_id(domain), assembly); + String name = mono_assembly_name_get_name(aname); + bool has_extension = name.ends_with(".dll") || name.ends_with(".exe"); - return assembly->get_assembly(); -} + if (no_search) + return NULL; -MonoAssembly *gdmono_MonoAssemblyPreLoad(MonoAssemblyName *aname, char **assemblies_path, void *user_data) { + GDMonoAssembly **loaded_asm = GDMono::get_singleton()->get_loaded_assembly(has_extension ? name.get_basename() : name); + if (loaded_asm) + return (*loaded_asm)->get_assembly(); - (void)user_data; // UNUSED + no_search = true; // Avoid the recursion madness + + String path; + MonoAssembly *res = NULL; + + for (int i = 0; i < search_dirs.size(); i++) { + const String &search_dir = search_dirs[i]; - MonoAssembly *assembly_loaded = mono_assembly_loaded(aname); - if (assembly_loaded) // Already loaded - return assembly_loaded; + if (has_extension) { + path = search_dir.plus_file(name); + if (FileAccess::exists(path)) { + res = _load_assembly_from(name.get_basename(), path); + break; + } + } else { + path = search_dir.plus_file(name + ".dll"); + if (FileAccess::exists(path)) { + res = _load_assembly_from(name, path); + break; + } + + path = search_dir.plus_file(name + ".exe"); + if (FileAccess::exists(path)) { + res = _load_assembly_from(name, path); + break; + } + } + } - static Vector<String> search_dirs; + no_search = false; + + return res; +} + +MonoAssembly *GDMonoAssembly::_preload_hook(MonoAssemblyName *aname, char **assemblies_path, void *user_data) { + + (void)user_data; // UNUSED if (search_dirs.empty()) { search_dirs.push_back(GodotSharpDirs::get_res_temp_assemblies_dir()); @@ -80,35 +112,32 @@ MonoAssembly *gdmono_MonoAssemblyPreLoad(MonoAssemblyName *aname, char **assembl } } - String name = mono_assembly_name_get_name(aname); - bool has_extension = name.ends_with(".dll") || name.ends_with(".exe"); + return NULL; +} - String path; +MonoAssembly *GDMonoAssembly::_load_assembly_from(const String &p_name, const String &p_path) { - for (int i = 0; i < search_dirs.size(); i++) { - const String &search_dir = search_dirs[i]; + GDMonoAssembly *assembly = memnew(GDMonoAssembly(p_name, p_path)); - if (has_extension) { - path = search_dir.plus_file(name); - if (FileAccess::exists(path)) - return gdmono_load_assembly_from(name.get_basename(), path); - } else { - path = search_dir.plus_file(name + ".dll"); - if (FileAccess::exists(path)) - return gdmono_load_assembly_from(name, path); + MonoDomain *domain = mono_domain_get(); - path = search_dir.plus_file(name + ".exe"); - if (FileAccess::exists(path)) - return gdmono_load_assembly_from(name, path); - } + Error err = assembly->load(domain); + + if (err != OK) { + memdelete(assembly); + ERR_FAIL_V(NULL); } - return NULL; + GDMono::get_singleton()->add_assembly(domain ? mono_domain_get_id(domain) : 0, assembly); + + return assembly->get_assembly(); } void GDMonoAssembly::initialize() { - mono_install_assembly_preload_hook(&gdmono_MonoAssemblyPreLoad, NULL); + // TODO refonly as well? + mono_install_assembly_preload_hook(&GDMonoAssembly::_preload_hook, NULL); + mono_install_assembly_search_hook(&GDMonoAssembly::_search_hook, NULL); } Error GDMonoAssembly::load(MonoDomain *p_domain) { @@ -153,7 +182,7 @@ no_pdb: ERR_FAIL_COND_V(status != MONO_IMAGE_OK || assembly == NULL, ERR_FILE_CANT_OPEN); - if (mono_image_get_entry_point(image)) { + if (p_domain && mono_image_get_entry_point(image)) { // TODO should this be removed? do we want to call main? what other effects does this have? mono_jit_exec(p_domain, assembly, 0, NULL); } diff --git a/modules/mono/mono_gd/gd_mono_assembly.h b/modules/mono/mono_gd/gd_mono_assembly.h index 89e091549c..710b674622 100644 --- a/modules/mono/mono_gd/gd_mono_assembly.h +++ b/modules/mono/mono_gd/gd_mono_assembly.h @@ -86,6 +86,14 @@ class GDMonoAssembly { Vector<uint8_t> pdb_data; #endif + static bool no_search; + static Vector<String> search_dirs; + + static MonoAssembly *_search_hook(MonoAssemblyName *aname, void *user_data); + static MonoAssembly *_preload_hook(MonoAssemblyName *aname, char **assemblies_path, void *user_data); + + static MonoAssembly *_load_assembly_from(const String &p_name, const String &p_path); + friend class GDMono; static void initialize(); diff --git a/modules/mono/mono_gd/gd_mono_field.cpp b/modules/mono/mono_gd/gd_mono_field.cpp index 0c64380e31..c2d8eeaa32 100644 --- a/modules/mono/mono_gd/gd_mono_field.cpp +++ b/modules/mono/mono_gd/gd_mono_field.cpp @@ -279,11 +279,11 @@ void GDMonoField::set_value(MonoObject *p_object, const Variant &p_value) { } bool GDMonoField::get_bool_value(MonoObject *p_object) { - return UNBOX_BOOLEAN(get_value(p_object)); + return (bool)GDMonoMarshal::unbox<MonoBoolean>(get_value(p_object)); } int GDMonoField::get_int_value(MonoObject *p_object) { - return UNBOX_INT32(get_value(p_object)); + return GDMonoMarshal::unbox<int32_t>(get_value(p_object)); } String GDMonoField::get_string_value(MonoObject *p_object) { diff --git a/modules/mono/mono_gd/gd_mono_marshal.cpp b/modules/mono/mono_gd/gd_mono_marshal.cpp index b5419952de..b64915109f 100644 --- a/modules/mono/mono_gd/gd_mono_marshal.cpp +++ b/modules/mono/mono_gd/gd_mono_marshal.cpp @@ -41,11 +41,11 @@ namespace GDMonoMarshal { return mono_value_box(mono_domain_get(), CACHED_CLASS_RAW(m_t), raw); \ } -#define RETURN_UNBOXED_STRUCT(m_t, m_var_in) \ - { \ - float *raw = UNBOX_FLOAT_PTR(m_var_in); \ - MARSHALLED_IN(m_t, raw, ret); \ - return ret; \ +#define RETURN_UNBOXED_STRUCT(m_t, m_var_in) \ + { \ + float *raw = (float *)mono_object_unbox(m_var_in); \ + MARSHALLED_IN(m_t, raw, ret); \ + return ret; \ } Variant::Type managed_to_variant_type(const ManagedType &p_type) { @@ -453,30 +453,30 @@ Variant mono_object_to_variant(MonoObject *p_obj) { Variant mono_object_to_variant(MonoObject *p_obj, const ManagedType &p_type) { switch (p_type.type_encoding) { case MONO_TYPE_BOOLEAN: - return (bool)UNBOX_BOOLEAN(p_obj); + return (bool)unbox<MonoBoolean>(p_obj); case MONO_TYPE_I1: - return UNBOX_INT8(p_obj); + return unbox<int8_t>(p_obj); case MONO_TYPE_I2: - return UNBOX_INT16(p_obj); + return unbox<int16_t>(p_obj); case MONO_TYPE_I4: - return UNBOX_INT32(p_obj); + return unbox<int32_t>(p_obj); case MONO_TYPE_I8: - return UNBOX_INT64(p_obj); + return unbox<int64_t>(p_obj); case MONO_TYPE_U1: - return UNBOX_UINT8(p_obj); + return unbox<uint8_t>(p_obj); case MONO_TYPE_U2: - return UNBOX_UINT16(p_obj); + return unbox<uint16_t>(p_obj); case MONO_TYPE_U4: - return UNBOX_UINT32(p_obj); + return unbox<uint32_t>(p_obj); case MONO_TYPE_U8: - return UNBOX_UINT64(p_obj); + return unbox<uint64_t>(p_obj); case MONO_TYPE_R4: - return UNBOX_FLOAT(p_obj); + return unbox<float>(p_obj); case MONO_TYPE_R8: - return UNBOX_DOUBLE(p_obj); + return unbox<double>(p_obj); case MONO_TYPE_STRING: { String str = mono_string_to_godot((MonoString *)p_obj); @@ -554,29 +554,18 @@ Variant mono_object_to_variant(MonoObject *p_obj, const ManagedType &p_type) { // GodotObject if (CACHED_CLASS(GodotObject)->is_assignable_from(type_class)) { - GDMonoField *ptr_field = CACHED_FIELD(GodotObject, ptr); - - ERR_FAIL_NULL_V(ptr_field, Variant()); - - void *ptr_to_unmanaged = UNBOX_PTR(ptr_field->get_value(p_obj)); - - if (!ptr_to_unmanaged) // IntPtr.Zero - return Variant(); - - Object *object_ptr = static_cast<Object *>(ptr_to_unmanaged); - - if (!object_ptr) - return Variant(); - - return object_ptr; + Object *ptr = unbox<Object *>(CACHED_FIELD(GodotObject, ptr)->get_value(p_obj)); + return ptr ? Variant(ptr) : Variant(); } if (CACHED_CLASS(NodePath) == type_class) { - return UNBOX_PTR(CACHED_FIELD(NodePath, ptr)->get_value(p_obj)); + NodePath *ptr = unbox<NodePath *>(CACHED_FIELD(NodePath, ptr)->get_value(p_obj)); + return ptr ? Variant(*ptr) : Variant(); } if (CACHED_CLASS(RID) == type_class) { - return UNBOX_PTR(CACHED_FIELD(RID, ptr)->get_value(p_obj)); + RID *ptr = unbox<RID *>(CACHED_FIELD(RID, ptr)->get_value(p_obj)); + return ptr ? Variant(*ptr) : Variant(); } } break; diff --git a/modules/mono/mono_gd/gd_mono_marshal.h b/modules/mono/mono_gd/gd_mono_marshal.h index 5fbafa0acb..38dd22357d 100644 --- a/modules/mono/mono_gd/gd_mono_marshal.h +++ b/modules/mono/mono_gd/gd_mono_marshal.h @@ -36,21 +36,10 @@ namespace GDMonoMarshal { -#define UNBOX_CHAR_PTR(x) (char *)mono_object_unbox(x) -#define UNBOX_FLOAT_PTR(x) (float *)mono_object_unbox(x) - -#define UNBOX_DOUBLE(x) *(double *)mono_object_unbox(x) -#define UNBOX_FLOAT(x) *(float *)mono_object_unbox(x) -#define UNBOX_INT64(x) *(int64_t *)mono_object_unbox(x) -#define UNBOX_INT32(x) *(int32_t *)mono_object_unbox(x) -#define UNBOX_INT16(x) *(int16_t *)mono_object_unbox(x) -#define UNBOX_INT8(x) *(int8_t *)mono_object_unbox(x) -#define UNBOX_UINT64(x) *(uint64_t *)mono_object_unbox(x) -#define UNBOX_UINT32(x) *(uint32_t *)mono_object_unbox(x) -#define UNBOX_UINT16(x) *(uint16_t *)mono_object_unbox(x) -#define UNBOX_UINT8(x) *(uint8_t *)mono_object_unbox(x) -#define UNBOX_BOOLEAN(x) *(MonoBoolean *)mono_object_unbox(x) -#define UNBOX_PTR(x) mono_object_unbox(x) +template <typename T> +T unbox(MonoObject *p_obj) { + return *(T *)mono_object_unbox(p_obj); +} #define BOX_DOUBLE(x) mono_value_box(mono_domain_get(), CACHED_CLASS_RAW(double), &x) #define BOX_FLOAT(x) mono_value_box(mono_domain_get(), CACHED_CLASS_RAW(float), &x) |