Example #1
0
 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);
                }
            }
        }
Example #3
0
        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);
                    }
        }
Example #4
0
        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);
            }
        }
Example #5
0
        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);
                    }
        }
Example #6
0
        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();
        }
Example #7
0
        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);
                }
            }
        }
Example #8
0
        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();
        }
Example #9
0
 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);
             }
         }
     }
 }
Example #10
0
 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();
     }
 }
Example #11
0
 public void ReleaseNetReference(UInt64 objectId)
 {
     NetReference.OnRelease(objectId);
 }
Example #12
0
        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);
                            }
                        }
        }