internal IntPtr tpHandle; // PyType * //==================================================================== // Given a Python object, return the associated managed object or null. //==================================================================== internal static ManagedType GetManagedObject(IntPtr ob) { if (ob != IntPtr.Zero) { IntPtr tp = Runtime.PyObject_TYPE(ob); if (tp == Runtime.PyTypeType || tp == Runtime.PyCLRMetaType) { tp = ob; } int flags = (int)Marshal.ReadIntPtr(tp, TypeOffset.tp_flags); if ((flags & TypeFlags.Managed) != 0) { IntPtr op = (tp == ob) ? Marshal.ReadIntPtr(tp, TypeOffset.magic()) : Marshal.ReadIntPtr(ob, ObjectOffset.magic()); GCHandle gc = (GCHandle)op; return((ManagedType)gc.Target); } // In certain situations, we need to recognize a wrapped // exception class and be willing to unwrap the class :( if (Runtime.wrap_exceptions) { IntPtr e = Exceptions.UnwrapExceptionClass(ob); if ((e != IntPtr.Zero) && (e != ob)) { ManagedType m = GetManagedObject(e); Runtime.Decref(e); return(m); } } } return(null); }
internal static bool ToManagedValue(IntPtr value, Type obType, out Object result, bool setError) { // Common case: if the Python value is a wrapped managed object // instance, just return the wrapped object. ManagedType mt = ManagedType.GetManagedObject(value); result = null; // XXX - hack to support objects wrapped in old-style classes // (such as exception objects). if (Runtime.wrap_exceptions) { if (mt == null) { if (Runtime.PyObject_IsInstance( value, Exceptions.Exception ) > 0) { IntPtr p = Runtime.PyObject_GetAttrString(value, "_inner"); if (p != IntPtr.Zero) { // This is safe because we know that the __dict__ of // value holds a reference to _inner. value = p; Runtime.Decref(p); mt = ManagedType.GetManagedObject(value); } } IntPtr c = Exceptions.UnwrapExceptionClass(value); if ((c != IntPtr.Zero) && (c != value)) { value = c; Runtime.Decref(c); mt = ManagedType.GetManagedObject(value); } } } if (mt != null) { if (mt is CLRObject) { object tmp = ((CLRObject)mt).inst; if (obType.IsInstanceOfType(tmp)) { result = tmp; return(true); } string err = "value cannot be converted to {0}"; err = String.Format(err, obType); Exceptions.SetError(Exceptions.TypeError, err); return(false); } if (mt is ClassBase) { result = ((ClassBase)mt).type; return(true); } // shouldnt happen return(false); } if (value == Runtime.PyNone && !obType.IsValueType) { result = null; return(true); } if (obType.IsArray) { return(ToArray(value, obType, out result, setError)); } if (obType.IsEnum) { return(ToEnum(value, obType, out result, setError)); } // Conversion to 'Object' is done based on some reasonable // default conversions (Python string -> managed string, // Python int -> Int32 etc.). if (obType == objectType) { if (Runtime.IsStringType(value)) { return(ToPrimitive(value, stringType, out result, setError)); } else if (Runtime.PyBool_Check(value)) { return(ToPrimitive(value, boolType, out result, setError)); } else if (Runtime.PyInt_Check(value)) { return(ToPrimitive(value, int32Type, out result, setError)); } else if (Runtime.PyLong_Check(value)) { return(ToPrimitive(value, int64Type, out result, setError)); } else if (Runtime.PyFloat_Check(value)) { return(ToPrimitive(value, doubleType, out result, setError)); } else if (Runtime.PySequence_Check(value)) { return(ToArray(value, typeof(object[]), out result, setError)); } if (setError) { Exceptions.SetError(Exceptions.TypeError, "value cannot be converted to Object" ); } return(false); } // Conversion to 'Type' is done using the same mappings as above // for objects. if (obType == typeType) { if (value == Runtime.PyStringType) { result = stringType; return(true); } else if (value == Runtime.PyBoolType) { result = boolType; return(true); } else if (value == Runtime.PyIntType) { result = int32Type; return(true); } else if (value == Runtime.PyLongType) { result = int64Type; return(true); } else if (value == Runtime.PyFloatType) { result = doubleType; return(true); } else if (value == Runtime.PyListType || value == Runtime.PyTupleType) { result = typeof(object[]); return(true); } if (setError) { Exceptions.SetError(Exceptions.TypeError, "value cannot be converted to Type" ); } return(false); } return(ToPrimitive(value, obType, out result, setError)); }