public bool Serialize(IntPtr i, IntPtr r) { using (var instance = new NetReference(i)) using (var result = new NetVariant(r)) { try { result.String = Serializer.Current.Serialize(instance.Instance); return(true); } catch (Exception ex) { // TODO: Propagate this error to the user. Console.Error.WriteLine($"Error serializing .NET object: {ex.Message}"); return(false); } } }
private void Test <TResult>(Expression <Func <TestObject, TResult> > expression, TResult value, Action <NetVariant> assert) { _mock.Reset(); _mock.Setup(expression).Returns(value); var del = (Net.Internal.CodeGen.CodeGen.InvokeMethodDelegate)BuildInvokeMethodDelegate(((MethodCallExpression)expression.Body).Method.Name); using (var netReference = NetReference.CreateForObject(_mock.Object)) { using (var result = new NetVariant()) { Task task = null; del(netReference, NetVariantList.From(), result, ref task); _mock.Verify(expression, Times.Once); assert(result); } } }
public void ReadProperty(IntPtr p, IntPtr t, IntPtr r) { using (var property = new NetPropertyInfo(p)) using (var target = new NetReference(t)) using (var result = new NetVariant(r)) { var o = target.Instance; var propertInfo = o.GetType() .GetProperty(property.Name, BindingFlags.Instance | BindingFlags.Public); if (propertInfo == null) { throw new InvalidOperationException($"Invalid property {property.Name}"); } Helpers.PackValue(propertInfo.GetValue(o), result); } }
public IntPtr InstantiateType(IntPtr type) { try { var typeName = Utilities.ContainerToString(Interop.NetTypeInfo.GetFullTypeName(type)); var typeInfo = Type.GetType(typeName); if (typeInfo == null) { throw new InvalidOperationException($"Invalid type {typeName}"); } var netReference = NetReference.CreateForObject(TypeCreator.Create(typeInfo)); // When .NET collects this NetReference, we don't want it to delete this // handle. Ownership has been passed to the caller. return(Interop.NetReference.Clone(netReference.Handle)); } finally { Interop.NetTypeInfo.Destroy(type); } }
public void WriteProperty(IntPtr p, IntPtr t, IntPtr v) { using (var property = new NetPropertyInfo(p)) using (var target = new NetReference(t)) using (var value = new NetVariant(v)) { var o = target.Instance; var propertInfo = o.GetType() .GetProperty(property.Name, BindingFlags.Instance | BindingFlags.Public); if (propertInfo == null) { throw new InvalidOperationException($"Invalid property {property.Name}"); } object newValue = null; Helpers.Unpackvalue(ref newValue, value); propertInfo.SetValue(o, newValue); } }
public void Can_release_gc_handle() { WeakReference reference = null; NetReference instance = null; Task.Factory.StartNew(() => { var o = new TestObject(); reference = new WeakReference(o); instance = NetReference.CreateForObject(o); }).Wait(); // NetReference is still alive, so the weak reference must be alive as well. GC.Collect(GC.MaxGeneration); reference.IsAlive.Should().BeTrue(); instance.Dispose(); // NetReference has been destroyed, so the handle should have been released. GC.Collect(GC.MaxGeneration); reference.IsAlive.Should().BeFalse(); }
public void CallComponentCompleted(IntPtr t) { using (var target = new NetReference(t)) { var instance = target.Instance; var componentCompelted = instance as IQmlComponentCompleted; if (componentCompelted == null) { throw new Exception($"Type {instance.GetType().FullName} doesn't implement IQmlComponentCompleted"); } var result = componentCompelted.ComponentCompleted(); if (QmlNetConfig.ListenForExceptionsWhenInvokingTasks) { result?.ContinueWith( task => { QmlNetConfig.RaiseUnhandledTaskException(task.Exception); }, TaskContinuationOptions.OnlyOnFaulted); } } }
public void Can_invoke_method() { var o = new TestObject(); var type = NetTypeManager.GetTypeInfo <TestObject>(); type.EnsureLoaded(); var method = type.GetMethod(0); var instance = NetReference.CreateForObject(o); // This will jump to native, to then call the .NET delegate (round trip). // The purpose is to simulate Qml invoking a method, sending .NET instance back. // We will inspect the returned instance that it got back to verify that it using (var parameter = new NetVariant()) using (var list = new NetVariantList()) { parameter.Instance = instance; list.Add(parameter); Interop.Callbacks.InvokeMethod(method.Handle, instance.Handle, list.Handle, IntPtr.Zero); } o.Object.Should().NotBeNull(); ReferenceEquals(o.Object, o).Should().BeTrue(); }
public static void Pack(object source, NetVariant destination, Type type) { if (type == typeof(bool)) { destination.Bool = (bool)source; } else if (type == typeof(char)) { destination.Char = (char)source; } else if (type == typeof(float)) { destination.Float = (float)source; } else if (type == typeof(double)) { destination.Double = (double)source; } else if (type == typeof(int)) { destination.Int = (int)source; } else if (type == typeof(uint)) { destination.UInt = (uint)source; } else if (type == typeof(long)) { destination.Long = (long)source; } else if (type == typeof(ulong)) { destination.ULong = (ulong)source; } else if (type == typeof(string)) { destination.String = (string)source; } else if (type == typeof(DateTimeOffset)) { destination.DateTime = ((DateTimeOffset)source).DateTime; } else if (typeof(INetJsValue).IsAssignableFrom(type)) { destination.JsValue = ((NetJsValue.NetJsValueDynamic)source).JsValue; } else { if (type.IsEnum) { Pack(source, destination, type.GetEnumUnderlyingType()); } else { if (source == null) { destination.Clear(); } else { destination.Instance = NetReference.CreateForObject(source); } } } }
private static void LoadObject(NetVariant variant, object value) { if (value != null) { if (value is bool valueBool) { variant.Bool = valueBool; } else if (value is char valueChar) { variant.Char = valueChar; } else if (value is int valueInt) { variant.Int = valueInt; } else if (value is uint valueUInt) { variant.UInt = valueUInt; } else if (value is long valueLong) { variant.Long = valueLong; } else if (value is ulong valueULong) { variant.ULong = valueULong; } else if (value is float valueFloat) { variant.Float = valueFloat; } else if (value is double valueDouble) { variant.Double = valueDouble; } else if (value is string valueString) { variant.String = valueString; } else if (value is DateTimeOffset valueDateTimeOffset) { variant.DateTime = valueDateTimeOffset; } else if (value is NetJsValue valueJsValue) { variant.JsValue = valueJsValue; } else if (value is NetQObject valueQObject) { variant.QObject = valueQObject; } else { variant.Instance = NetReference.CreateForObject(value); } } else { variant.Clear(); } }
public void ReleaseNetReference(UInt64 objectId) { NetReference.OnRelease(objectId); }
public void InvokeMethod(IntPtr m, IntPtr t, IntPtr p, IntPtr r) { using (var method = new NetMethodInfo(m)) using (var target = new NetReference(t)) using (var parameters = new NetVariantList(p)) using (var result = r != IntPtr.Zero ? new NetVariant(r) : null) { var instance = target.Instance; List <object> methodParameters = null; if (parameters.Count > 0) { methodParameters = new List <object>(); var parameterCount = parameters.Count; for (var x = 0; x < parameterCount; x++) { object v = null; Helpers.Unpackvalue(ref v, parameters.Get(x)); methodParameters.Add(v); } } MethodInfo methodInfo = null; var methodName = method.MethodName; var methods = instance.GetType() .GetMethods(BindingFlags.Instance | BindingFlags.Public) .Where(x => x.Name == methodName) .ToList(); if (methods.Count == 1) { methodInfo = methods[0]; } else if (methods.Count > 1) { // This is an overload. // TODO: Make this more performant. https://github.com/pauldotknopf/Qml.Net/issues/39 // Get all the parameters for the method we are invoking. var parameterTypes = method.GetAllParameters().Select(x => x.Type.FullTypeName).ToList(); // And find a good method to invoke. foreach (var potentialMethod in methods) { var potentialMethodParameters = potentialMethod.GetParameters(); if (potentialMethodParameters.Length != parameterTypes.Count) { continue; } bool valid = true; for (var x = 0; x < potentialMethodParameters.Length; x++) { if (potentialMethodParameters[x].ParameterType.AssemblyQualifiedName != parameterTypes[x]) { valid = false; break; } } if (valid) { methodInfo = potentialMethod; break; } } } if (methodInfo == null) { throw new InvalidOperationException($"Invalid method name {method.MethodName}"); } var returnObject = methodInfo.Invoke(instance, methodParameters?.ToArray()); if (result == null) { // this method doesn't have return type } else { Helpers.PackValue(returnObject, result); } } }