mono::object ToMonoObject(ScriptAnyValue anyValue) { switch(anyValue.type) { case ANY_TSTRING: return (mono::object)ToMonoString(anyValue.str); case ANY_TNUMBER: return (mono::object)mono_value_box(mono_domain_get(), mono_get_single_class(), &anyValue.number); case ANY_TBOOLEAN: return (mono::object)mono_value_box(mono_domain_get(), mono_get_boolean_class(), &anyValue.b); case ANY_TVECTOR: { IMonoClass *pVec3Class = g_pScriptSystem->GetCryBraryAssembly()->GetClass("Vec3"); Vec3 vec(anyValue.vec3.x, anyValue.vec3.y, anyValue.vec3.z); return pVec3Class->BoxObject(&vec)->GetManagedObject(); } case ANY_TTABLE: return (mono::object)anyValue.table; default: break; } return nullptr; }
mono::object CScriptClass::BoxObject(void *object, IMonoDomain *pDomain) { if(pDomain == nullptr) pDomain = GetMonoScriptSystem()->GetActiveDomain(); return (mono::object)mono_value_box(static_cast<CScriptDomain *>(pDomain)->GetMonoDomain(), (MonoClass *)m_pObject, object); }
static guint64 debugger_get_boxed_object (guint64 klass_arg, guint64 val_arg) { static MonoObject *last_boxed_object = NULL; MonoClass *klass = (MonoClass *) GUINT_TO_POINTER ((gsize) klass_arg); gpointer val = (gpointer) GUINT_TO_POINTER ((gsize) val_arg); MonoObject *boxed; if (!mono_class_is_valuetype (klass)) return val_arg; boxed = mono_value_box (mono_domain_get (), klass, val); last_boxed_object = boxed; // Protect the object from being garbage collected return (guint64) (gsize) boxed; }
/* * plmono_trigger_build_args * * Create TableRow object based trigger's "OLD" row tuple */ void plmono_trigger_build_args(TriggerData *trigdata, MonoObject *cols) { MonoClass *rowklass; MonoClass *objklass; MonoMethod* additem; TupleDesc resdesc; gpointer kvpair[2]; char *attname; Oid atttype; Datum *atts; bool *nulls; gpointer val; int i; resdesc = trigdata->tg_relation->rd_att; if (!(atts = palloc(resdesc->natts * sizeof(Datum)))) elog(ERROR, "Not enough memory"); if (!(nulls = palloc(resdesc->natts * sizeof(bool)))) elog(ERROR, "Not enough memory"); heap_deform_tuple(trigdata->tg_trigtuple, resdesc, atts, nulls); rowklass = mono_object_get_class(cols); additem = mono_class_get_method_from_name(rowklass, "Add", 2); for (i = 0; i < resdesc->natts; i++) { attname = NameStr(resdesc->attrs[i]->attname); atttype = resdesc->attrs[i]->atttypid; val = plmono_datum_to_obj(atts[i], atttype); objklass = plmono_typeoid_to_class(atttype); kvpair[0] = mono_string_new(plmono_get_domain(), attname); /* attribute name */ //elog(ERROR, "Val %p ObjClass %p", val, objklass); if (atttype != TEXTOID) kvpair[1] = mono_value_box(plmono_get_domain(), objklass, val); /* attribute value */ else kvpair[1] = val; mono_runtime_invoke(additem, cols, kvpair, NULL); } }
mono::object CScriptDomain::BoxAnyValue(MonoAnyValue &any) { switch(any.type) { case eMonoAnyType_Boolean: return (mono::object)mono_value_box(m_pDomain, mono_get_boolean_class(), &any.b); case eMonoAnyType_Integer: return (mono::object)mono_value_box(m_pDomain, mono_get_int32_class(), &any.i); case eMonoAnyType_UnsignedInteger: return (mono::object)mono_value_box(m_pDomain, mono_get_uint32_class(), &any.u); case eMonoAnyType_Short: return (mono::object)mono_value_box(m_pDomain, mono_get_int16_class(), &any.i); case eMonoAnyType_UnsignedShort: return (mono::object)mono_value_box(m_pDomain, mono_get_uint16_class(), &any.u); case eMonoAnyType_Float: return (mono::object)mono_value_box(m_pDomain, mono_get_single_class(), &any.f); case eMonoAnyType_String: return (mono::object)CreateMonoString(any.str); case eMonoAnyType_EntityId: { IMonoClass *pEntityIdClass = g_pScriptSystem->GetCryBraryAssembly()->GetClass("EntityId"); return pEntityIdClass->BoxObject(&mono::entityId(any.u), this); } case eMonoAnyType_Vec3: { IMonoClass *pVec3Class = g_pScriptSystem->GetCryBraryAssembly()->GetClass("Vec3"); Vec3 vec3(any.vec4.x, any.vec4.y, any.vec4.z); return pVec3Class->BoxObject(&vec3, this); } break; case eMonoAnyType_Quat: { IMonoClass *pQuatClass = g_pScriptSystem->GetCryBraryAssembly()->GetClass("Quat"); return pQuatClass->BoxObject(&any.vec4, this); } break; case eMonoAnyType_Array: case eMonoAnyType_Unknown: return any.monoObject; } return nullptr; }
void mono_threadpool_ms_enqueue_work_item (MonoDomain *domain, MonoObject *work_item) { static MonoClass *threadpool_class = NULL; static MonoMethod *unsafe_queue_custom_work_item_method = NULL; MonoDomain *current_domain; MonoBoolean f; gpointer args [2]; g_assert (work_item); if (!threadpool_class) threadpool_class = mono_class_from_name (mono_defaults.corlib, "System.Threading", "ThreadPool"); g_assert (threadpool_class); if (!unsafe_queue_custom_work_item_method) unsafe_queue_custom_work_item_method = mono_class_get_method_from_name (threadpool_class, "UnsafeQueueCustomWorkItem", 2); g_assert (unsafe_queue_custom_work_item_method); f = FALSE; args [0] = (gpointer) work_item; args [1] = (gpointer) mono_value_box (domain, mono_defaults.boolean_class, &f); current_domain = mono_domain_get (); if (current_domain == domain) { mono_runtime_invoke (unsafe_queue_custom_work_item_method, NULL, args, NULL); } else { mono_thread_push_appdomain_ref (domain); if (mono_domain_set (domain, FALSE)) { mono_runtime_invoke (unsafe_queue_custom_work_item_method, NULL, args, NULL); mono_domain_set (current_domain, TRUE); } mono_thread_pop_appdomain_ref (); } }
mono::object CScriptDomain::BoxAnyValue(MonoAnyValue &any) { switch(any.type) { case eMonoAnyType_Boolean: return (mono::object)mono_value_box(m_pDomain, mono_get_boolean_class(), &any.b); case eMonoAnyType_Integer: return (mono::object)mono_value_box(m_pDomain, mono_get_int32_class(), &any.i); case eMonoAnyType_UnsignedInteger: return (mono::object)mono_value_box(m_pDomain, mono_get_uint32_class(), &any.u); case eMonoAnyType_EntityId: { IMonoClass *pEntityIdClass = g_pScriptSystem->GetCryBraryAssembly()->GetClass("EntityId"); return pEntityIdClass->BoxObject(&mono::entityId(any.u), this)->GetManagedObject(); } case eMonoAnyType_Short: return (mono::object)mono_value_box(m_pDomain, mono_get_int16_class(), &any.i); case eMonoAnyType_UnsignedShort: return (mono::object)mono_value_box(m_pDomain, mono_get_uint16_class(), &any.u); case eMonoAnyType_Float: return (mono::object)mono_value_box(m_pDomain, mono_get_single_class(), &any.f); case eMonoAnyType_String: MonoWarning("IMonoConverter::BoxAnyValue does not support strings, utilize ToMonoString instead"); case eMonoAnyType_Vec3: { IMonoClass *pVec3Class = g_pScriptSystem->GetCryBraryAssembly()->GetClass("Vec3"); Vec3 vec3(any.vec4.x, any.vec4.y, any.vec4.z); return pVec3Class->BoxObject(&vec3, this)->GetManagedObject(); } break; case eMonoAnyType_Quat: { IMonoClass *pQuatClass = g_pScriptSystem->GetCryBraryAssembly()->GetClass("Quat"); return pQuatClass->BoxObject(&any.vec4, this)->GetManagedObject(); } break; } return nullptr; }
MonoObject* JniManager::toMonoObject(JNIEnv* env, jobject obj) { assert(env); MonoDomain* monoDomain = getMonoDomain(); MonoObject* result = NULL; jclass clazz = env->GetObjectClass(obj); jstring clazzName = (jstring)env->CallObjectMethod(clazz, typeConverter->getClassName); string className = string(typeConverter->convertToC<string>(env, clazzName)); if (className == "java.lang.Integer") { int value = typeConverter->convertToC<int>(env, obj); result = mono_value_box(monoDomain, mono_get_int32_class(), &value); } if (className == "java.lang.String") { string value = typeConverter->convertToC<string>(env, obj); result = (MonoObject*)mono_string_new(monoDomain, value.c_str()); } if (className == "java.lang.Boolean") { bool value = typeConverter->convertToC<bool>(env, obj); result = (MonoObject*)mono_value_box(monoDomain, mono_get_boolean_class(), &value); } if (className == "java.lang.Character") { char value = typeConverter->convertToC<char>(env, obj); result = (MonoObject*)mono_value_box(monoDomain, mono_get_char_class(), &value); } if (className == "java.lang.Long") { long value = typeConverter->convertToC<long>(env, obj); result = (MonoObject*)mono_value_box(monoDomain, mono_get_int64_class(), &value); } if (className == "java.lang.Short") { short value = typeConverter->convertToC<short>(env, obj); result = (MonoObject*)mono_value_box(monoDomain, mono_get_int16_class(), &value); } if (className =="java.lang.Byte") { byte value = typeConverter->convertToC<byte>(env, obj); result = (MonoObject*)mono_value_box(monoDomain, mono_get_byte_class(), &value); } if (className == "java.lang.Double" ) { double value = typeConverter->convertToC<double>(env, obj); result = (MonoObject*)mono_value_box(monoDomain, mono_get_double_class(), &value); } if (className == "java.lang.Float" ) { float value = typeConverter->convertToC<float>(env, obj); result = (MonoObject*)mono_value_box(monoDomain, mono_get_single_class(), &value); } if (className == "[B") { vector<byte> value = typeConverter->convertToC< vector<byte> >(env, obj); int vectorSize = value.size(); MonoArray *data = mono_array_new (monoDomain, mono_get_byte_class (), vectorSize); for (int i=0; i<vectorSize; i++) { mono_array_set(data, uint8_t, i, value[i]); } result = (MonoObject*)data; } env->DeleteLocalRef(obj); return result; }
static int param_to_mono_array (caddr_t *list_args, int n_args, MonoArray ** p_i_array, MonoArray **p_o_array) { caddr_t * line; MonoObject *arg = NULL; MonoDomain *domain = virtuoso_domain; MonoArray *i_array, *o_array; guint32 is_object; int inx; i_array = (MonoArray*)mono_array_new (domain, mono_get_object_class (), n_args); o_array = (MonoArray*)mono_array_new (domain, mono_get_intptr_class (), n_args); for (inx = 0; inx < n_args; ++inx) { line = (caddr_t *) list_args[inx]; is_object = 0; if (DV_TYPE_OF (line[1]) == DV_DB_NULL) { arg = NULL; goto put_it; } if (!strncmp (line[0], "System.String", sizeof ("System.String")) || !strncmp (line[0], "String", sizeof ("String"))) { if (!DV_STRINGP (line[1])) goto convert_error; arg = (MonoObject *) mono_string_new (domain, line[1]); } else if (!strncmp (line[0], "Int32", sizeof ("Int32")) || !strncmp (line[0], "System.Int32", sizeof ("System.Int32")) || !strncmp (line[0], "int", sizeof ("int"))) { gint32 ivalue; if (DV_TYPE_OF (line[1]) != DV_LONG_INT) goto convert_error; ivalue = unbox (line[1]); arg = mono_value_box (domain, mono_get_int32_class (), &ivalue); } else if (!strncmp (line[0], "System.Single", sizeof ("System.Single")) || !strncmp (line[0], "Single", sizeof ("Single"))) { float flt_value; if (DV_TYPE_OF (line[1]) != DV_SINGLE_FLOAT) goto convert_error; flt_value = unbox_float (line[1]); arg = mono_value_box (domain, mono_get_single_class (), &flt_value); } else if (!strncmp (line[0], "System.Data.SqlTypes.SqlDouble", sizeof ("System.Data.SqlTypes.SqlDouble")) || !strncmp (line[0], "System.Double", sizeof ("System.Double")) || !strncmp (line[0], "Double", sizeof ("Double"))) { double dbl_value; if (DV_TYPE_OF (line[1]) != DV_DOUBLE_FLOAT) goto convert_error; dbl_value = unbox_double (line[1]); arg = mono_value_box (domain, mono_get_double_class (), &dbl_value); } else /*if (!strncmp (line[0], "CLRObject", sizeof ("CLRObject"))) */ { gint32 ivalue; if (DV_TYPE_OF (line[1]) != DV_LONG_INT) goto convert_error; is_object = unbox (line[1]); arg = mono_value_box (domain, mono_get_int32_class (), &ivalue); } put_it: mono_array_set (i_array, gpointer, inx, arg); mono_array_set (o_array, gpointer, inx, (gpointer) is_object); } *p_i_array = i_array; *p_o_array = o_array; return 0; convert_error: sqlr_new_error ("22023", "XXXXX", "wrong or unknown type"); return 0; }
/* * 将由lua传入的参数表转化为void *[]参数表 * L : 含有参数表的lua_State * base : 参数表在lua_State中的起始位置(靠近栈底的一边) * method : 参数表将要应用到的MonoMethod* * * 该调用只针对Static methods, 和 non-Static methods, 不针对generic methods */ static void *call_method (lua_State *L, int base, MonoObject *thiz, MonoMethod *method, MonoObject **ex) { MonoMethodSignature *sig = mono_method_signature (method); if (!sig) luaL_error (L, "can not get the method's signature."); int n = mono_signature_get_param_count (sig); int cur_n = lua_gettop (L) - base + 1; if (cur_n != n) { /*Fixme : mono_method_full_name 的返回值需要显示 g_free*/ luaL_error (L, "%s need %d arguments, but get %d.", mono_method_full_name (method, 1), n, cur_n); } void **args = 0; if (n > 0) args = new void*[n]; void *iter = 0; MonoType *param_type; for (int i = 0; (param_type = mono_signature_get_params (sig, &iter)) != 0; i++) { /*reference 类型的参数 无论是否加ref关键字, 都是传递改类型对象指针的指针*/ if (mono_type_is_reference (param_type) || mono_type_is_byref (param_type)) { void *p = lua_touserdata (L, base + i); if (!p) luaL_error (L, "%s : %d arg need a reference type.", mono_method_full_name (method, 1), i); args[i] = p; continue; } /*剩下的都是value类型*/ switch (mono_type_get_type (param_type)) { case MONO_TYPE_BOOLEAN: { int b = lua_toboolean (L, base + i); MonoObject *obj = mono_value_box (mono_domain_get (), mono_get_boolean_class (), &b); args[i] = mono_object_unbox (obj); break; } case MONO_TYPE_CHAR: { /*char 用int来表示*/ int b = luaL_checkint (L, base + i); MonoObject *obj = mono_value_box (mono_domain_get (), mono_get_char_class (), &b); args[i] = mono_object_unbox (obj); break; } case MONO_TYPE_I1: { int b = luaL_checkint (L, base + i); MonoObject *obj = mono_value_box (mono_domain_get (), mono_get_sbyte_class (), &b); args[i] = mono_object_unbox (obj); break; } case MONO_TYPE_U1: { unsigned long l = luaL_checkunsigned (L, base + i); MonoObject *obj = mono_value_box (mono_domain_get (), mono_get_byte_class (), &l); args[i] = mono_object_unbox (obj); break; } case MONO_TYPE_I2: { int b = luaL_checkint (L, base + i); MonoObject *obj = mono_value_box (mono_domain_get (), mono_get_int16_class (), &b); args[i] = mono_object_unbox (obj); break; } case MONO_TYPE_U2: { unsigned long l = luaL_checkunsigned (L, base + i); MonoObject *obj = mono_value_box (mono_domain_get (), mono_get_uint16_class (), &l); args[i] = mono_object_unbox (obj); break; } case MONO_TYPE_I4: { int b = luaL_checkint (L, base + i); MonoObject *obj = mono_value_box (mono_domain_get (), mono_get_int32_class (), &b); args[i] = mono_object_unbox (obj); break; } case MONO_TYPE_VALUETYPE: case MONO_TYPE_U4: { unsigned long l = luaL_checkunsigned (L, base + i); MonoObject *obj = mono_value_box (mono_domain_get (), mono_get_uint32_class (), &l); args[i] = mono_object_unbox (obj); break; } case MONO_TYPE_I8: { void *u = lua_touserdata (L, base + i); if (!u) luaL_error (L, "%s : %d arg need Int64.", mono_method_full_name (method, 1), i); MonoObject *obj = mono_value_box (mono_domain_get (), mono_get_int64_class (), u); args[i] = mono_object_unbox (obj); break; } case MONO_TYPE_U8: { void *u = lua_touserdata (L, base + i); if (!u) luaL_error (L, "%s : %d arg need UInt64.", mono_method_full_name (method, 1), i); MonoObject *obj = mono_value_box (mono_domain_get (), mono_get_uint64_class (), u); args[i] = mono_object_unbox (obj); break; } case MONO_TYPE_R4: { /*这里的精度损失由使用lua的人负责*/ float f = (float)lua_tonumber (L, base + i); MonoObject *obj = mono_value_box (mono_domain_get (), mono_get_single_class (), &f); args[i] = mono_object_unbox (obj); break; } case MONO_TYPE_R8: { double d = (double)lua_tonumber (L, base + i); MonoObject *obj = mono_value_box (mono_domain_get (), mono_get_double_class (), &d); args[i] = mono_object_unbox (obj); break; } case MONO_TYPE_I: { void *u = lua_touserdata (L, base + i); if (!u) luaL_error (L, "%s : %d arg need IntPtr.", mono_method_full_name (method, 1), i); MonoObject *obj = mono_value_box (mono_domain_get (), mono_get_intptr_class (), u); args[i] = mono_object_unbox (obj); break; } case MONO_TYPE_U: { void *u = lua_touserdata (L, base + i); if (!u) luaL_error (L, "%s : %d arg need UIntPtr.", mono_method_full_name (method, 1), i); MonoObject *obj = mono_value_box (mono_domain_get (), mono_get_uintptr_class (), u); args[i] = mono_object_unbox (obj); break; } case MONO_TYPE_MVAR: luaL_error (L, "generic method dont be supported."); case MONO_TYPE_PTR: luaL_error (L, "dont support the ptr type."); default: luaL_error (L, "unknow method args type : 0x%02X", mono_type_get_type (param_type)); } } MonoObject *ret = mono_runtime_invoke (method, thiz, args, ex); //MonoType *ret_type = mono_signature_get_return_type (sig); LOGD ("call_method be called!"); return ret; }
void CDynScriptArray::InsertNativePointer(void *ptr, int index) { CScriptDomain *pDomain = static_cast<CScriptDomain *>(GetClass()->GetAssembly()->GetDomain()); Insert((mono::object)mono_value_box(pDomain->GetMonoDomain(), mono_get_intptr_class(), ptr), index); }