public static Func <IntPtr, object> build(Type tInterface) { Guid iid = ReflectionUtils.checkInterface(tInterface); InterfaceBuilder ib = new InterfaceBuilder(tInterface); Type tProxy = ib.build(); int methodsCount = ib.methodsCount; Expression <Func <IntPtr, IntPtr[]> > eReadVtbl = ( IntPtr nativeComPointer ) => RuntimeClass.readVirtualTable(nativeComPointer, methodsCount); ConstantExpression eIid = Expression.Constant(iid, typeof(Guid)); Expression[] baseCtorArgs = new Expression[3] { paramNativeObject, Expression.Invoke(eReadVtbl, paramNativeObject), eIid }; if (!ib.anyCustomMethods) { // Simple case here, no custom marshalers. No need to do late binding, just compile the factory that creates new proxy return(buildSimpleFactory(tProxy, baseCtorArgs)); } var customFactory = buildCustomFactory(tProxy, baseCtorArgs, ib); var lateBinder = createLateBinder(ib.customMethods); return(( IntPtr nativeComPointer ) => { IntPtr[] vtable = RuntimeClass.readVirtualTable(nativeComPointer, methodsCount); Delegate[] marshallers = lateBinder(nativeComPointer, vtable); return customFactory(nativeComPointer, vtable, marshallers); }); }
public unsafe void StructsMarshaling() { var random = new Random(); var twoRegistersResult = new RuntimeClass("NSString").InvokeObject("stringWithString:", "First second third").InvokeStruct <NObjective.Proxies._NSRange>("rangeOfString:", "second"); Assert.AreEqual(6, twoRegistersResult.location); Assert.AreEqual(6, twoRegistersResult.length); var originalMatrix = new NObjective.Proxies.CATransform3D(); float *originalMatrixPtr = &originalMatrix.m11; for (int i = 0; i < 16; i++) { originalMatrixPtr[i] = ( float )random.NextDouble(); } var newMatrix = new RuntimeClass("NSValue").InvokeObject("valueWithCATransform3D:", originalMatrix).InvokeStruct <NObjective.Proxies.CATransform3D>("CATransform3DValue"); float *newMatrixPtr = &newMatrix.m11; for (int i = 0; i < 16; i++) { Assert.AreEqual(originalMatrixPtr[i], newMatrixPtr[i]); } }
public void ManualRegistrationTest() { Assert.AreEqual(false, RuntimeClass.GetAllClasses().Any(x => x.Name == Runtime.GetExportedClassName <ManualRegisteredClass>())); Assert.AreEqual(false, Runtime.IsClassExportedByRuntime(Runtime.GetExportedClass <ManualRegisteredClass>())); Runtime.ExportClass(typeof(ManualRegisteredClass)); Assert.AreEqual(true, Runtime.IsClassExportedByRuntime(Runtime.GetExportedClass <ManualRegisteredClass>())); var proxy = Runtime.CreateInstance <ManualRegisteredClass>("init"); }
public static void add(IntPtr p, RuntimeClass rc) { Debug.Assert(p != IntPtr.Zero); lock ( syncRoot ) { WeakRefSet set; if (!native.TryGetValue(p, out set)) { set = new WeakRefSet(); native.Add(p, set); } set.Add(new WeakRef(rc)); } }
public static void add(IntPtr p, RuntimeClass rc) { Debug.Assert(p != IntPtr.Zero); lock ( syncRoot ) { InterfacesMap map; if (!native.TryGetValue(p, out map)) { map = new InterfacesMap(); native.Add(p, map); } map.GetValue(rc, ifacesCallback); } }
public static bool drop(IntPtr p, RuntimeClass rc) { lock ( syncRoot ) { if (native.TryGetValue(p, out InterfacesMap map)) { bool removed = map.Remove(rc); if (!map.Any()) { native.Remove(p); } return(removed); } return(false); } }
public static bool drop(IntPtr p, RuntimeClass rc) { lock ( syncRoot ) { WeakRefSet set; if (!native.TryGetValue(p, out set)) { return(false); } bool found = false; foreach (WeakRef wr in set) { if (!wr.TryGetTarget(out RuntimeClass r)) { deadRefs.Add(wr); continue; } if (r == rc) { found = true; deadRefs.Add(wr); } else if (!rc.isAlive()) { deadRefs.Add(wr); } } foreach (var wr in deadRefs) { set.Remove(wr); } deadRefs.Clear(); if (set.Count <= 0) { native.Remove(p); } return(found); } }
/// <summary> /// Validate the object. /// </summary> /// <exception cref="ValidationException"> /// Thrown if validation fails /// </exception> public virtual void Validate() { if (FsGroup == null) { throw new ValidationException(ValidationRules.CannotBeNull, "FsGroup"); } if (RunAsUser == null) { throw new ValidationException(ValidationRules.CannotBeNull, "RunAsUser"); } if (SeLinux == null) { throw new ValidationException(ValidationRules.CannotBeNull, "SeLinux"); } if (SupplementalGroups == null) { throw new ValidationException(ValidationRules.CannotBeNull, "SupplementalGroups"); } if (AllowedCSIDrivers != null) { foreach (var element in AllowedCSIDrivers) { if (element != null) { element.Validate(); } } } if (AllowedFlexVolumes != null) { foreach (var element1 in AllowedFlexVolumes) { if (element1 != null) { element1.Validate(); } } } if (HostPorts != null) { foreach (var element2 in HostPorts) { if (element2 != null) { element2.Validate(); } } } if (RunAsGroup != null) { RunAsGroup.Validate(); } if (RunAsUser != null) { RunAsUser.Validate(); } if (RuntimeClass != null) { RuntimeClass.Validate(); } if (SeLinux != null) { SeLinux.Validate(); } }
public static void Dump(string profileName) { if (!ProxyBuilder.IsRunningOnMacintosh) { return; } // load classes from specified frameworks foreach (var setting in Settings.Frameworks) { setting.Path = setting.Path ?? string.Format("/System/Library/Frameworks/{0}.framework/{0}", setting.Name); Console.WriteLine("Loading library {0}..", setting.Path); NativeMethods.dlopen(setting.Path, 0x1); } var result = new ObjectiveCRuntimeInfo { OSVersion = Runtime.Version.ToString() }; var libraries = new Dictionary <string, ObjectiveCRuntimeInfo.LibraryInfo>(); var dumpedMethods = new HashSet <string>(); Action <string> createLibary = (libraryName) => { if (!libraries.ContainsKey(libraryName)) { libraries[libraryName] = new ObjectiveCRuntimeInfo.LibraryInfo(); libraries[libraryName].Path = libraryName; } }; foreach (var @class in RuntimeClass.GetAllClasses()) { var className = @class.Name; if (!ClassExcludeFilters.All(x => !x.IsMatch(className)) || !ClassIncludeFilters.Any(x => x.IsMatch(className))) { continue; } if (Runtime.IsInternalProxyClass(@class)) { continue; } var classSetting = new ObjectiveCRuntimeInfo.ClassInfo { Name = className }; var libraryName = @class.DeclaringImage; // for generated classes if (libraryName == null) { var baseImage = "/usr/lib/libobjc.A.dylib"; foreach (var item in @class.BaseClass.BaseHierarchy) { if (item.DeclaringImage == null) { continue; } baseImage = item.DeclaringImage; break; } libraryName = baseImage; } createLibary(libraryName); if (@class.BaseClass != RuntimeClass.Null) { classSetting.BaseClassName = @class.BaseClass.Name; } dumpedMethods.Clear(); foreach (var method in @class.Methods) { var methodName = method.Name; var methodLibrary = method.DeclaringImage; if (!MethodExcludeFilters.All(x => !x.IsMatch(methodName)) || dumpedMethods.Contains(methodName)) { continue; } dumpedMethods.Add(methodName); if (methodLibrary != libraryName) { createLibary(methodLibrary); var extensionsClass = libraries[methodLibrary].Extensions.FirstOrDefault(x => x.Name == className); if (extensionsClass == null) { extensionsClass = new ObjectiveCRuntimeInfo.ClassInfo { Name = className }; libraries[methodLibrary].Extensions.Add(extensionsClass); } extensionsClass.InstanceMethods.Add(new ObjectiveCRuntimeInfo.MethodInfo { Name = method.Name, Encoding = method.Encoding }); continue; } classSetting.InstanceMethods.Add(new ObjectiveCRuntimeInfo.MethodInfo { Name = method.Name, Encoding = method.Encoding }); } foreach (var property in @class.Properties) { classSetting.Properties = classSetting.Properties ?? new List <ObjectiveCRuntimeInfo.PropertyInfo>(); classSetting.Properties.Add(new ObjectiveCRuntimeInfo.PropertyInfo { Name = property.Name, Encoding = property.Attributes }); } dumpedMethods.Clear(); foreach (var method in @class.MetaClass.Methods) { var methodName = method.Name; var methodLibrary = method.DeclaringImage; if (!MethodExcludeFilters.All(x => !x.IsMatch(methodName)) || dumpedMethods.Contains(methodName)) { continue; } dumpedMethods.Add(methodName); if (methodLibrary != libraryName) { createLibary(methodLibrary); var extensionsClass = libraries[methodLibrary].Extensions.FirstOrDefault(x => x.Name == className); if (extensionsClass == null) { extensionsClass = new ObjectiveCRuntimeInfo.ClassInfo { Name = className }; libraries[methodLibrary].Extensions.Add(extensionsClass); } extensionsClass.ClassMethods.Add(new ObjectiveCRuntimeInfo.MethodInfo { Name = method.Name, Encoding = method.Encoding }); continue; } classSetting.ClassMethods.Add(new ObjectiveCRuntimeInfo.MethodInfo { Name = methodName, Encoding = method.Encoding }); } libraries[libraryName].Classes.Add(classSetting); } result.Libraries = libraries.Select(x => x.Value).OrderBy(x => x.Path).ToList(); foreach (var library in result.Libraries) { library.Classes = library.Classes.OrderBy(x => x.Name).ToList(); foreach (var @class in library.Classes) { @class.ClassMethods = @class.ClassMethods.OrderBy(x => x.Name).ToList(); @class.InstanceMethods = @class.InstanceMethods.OrderBy(x => x.Name).ToList(); if (@class.Properties != null) { @class.Properties = @class.Properties.OrderBy(x => x.Name).ToList(); } } } using (var file = new StreamWriter(string.Format(OutputFilename, profileName))) new XmlSerializer(result.GetType()).Serialize(file, result); Console.WriteLine("Dump information:"); Console.WriteLine(" {0} libraries", result.Libraries.Count); Console.WriteLine(" {0} classes", result.Libraries.Sum(x => x.Classes.Count)); Console.WriteLine(" {0} methods", result.Libraries.SelectMany(x => x.Classes).Sum(x => x.ClassMethods.Count + x.InstanceMethods.Count)); Console.WriteLine(" {0} properties", result.Libraries.SelectMany(x => x.Classes).Sum(x => x.Properties == null ? 0 : x.Properties.Count)); }
/// <summary>Array of COM interface types implemented by RuntimeClass proxy. We now support interfaces inheritance, a proxy may implement more than one.</summary> /// <remarks>It's gonna be quite short anyway, most often just 1 interface, sometimes 2-3. That's why array instead of a hash map.</remarks> static Type[] collectComInterfaces(RuntimeClass rc) { return(rc.GetType().GetInterfaces() .Where(i => i.hasCustomAttribute <ComInterfaceAttribute>()) .ToArray()); }
public RuntimeClass ReturnClass(RuntimeClass @class) { return(@class); }