Inheritance: System.Attribute
 public void ImportMembers()
 {
     foreach (FieldInfo field in this.GetType().GetFields(BindingFlags.DeclaredOnly | BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance))
     {
         ConnectAttribute attr = (ConnectAttribute)Attribute.GetCustomAttribute(field, typeof(ConnectAttribute));
         if (attr != null)
         {
             string name         = (attr.Name != null ? attr.Name : field.Name);
             IntPtr native_value = Marshal.AllocHGlobal(Marshal.SizeOf(typeof(IntPtr)));
             ObjCMethods.object_getInstanceVariable(this.NativeObject, name, native_value);
             field.SetValue(this, field.FieldType.IsPrimitive ? Marshal.PtrToStructure(native_value, field.FieldType) : Object.FromIntPtr(Marshal.ReadIntPtr(native_value)));
             Marshal.FreeHGlobal(native_value);
         }
     }
 }
        public void ExportMembers()
        {
            foreach (FieldInfo field in this.GetType().GetFields(BindingFlags.DeclaredOnly | BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance))
            {
                ConnectAttribute attr = (ConnectAttribute)Attribute.GetCustomAttribute(field, typeof(ConnectAttribute));
                if (attr != null)
                {
                    string name          = (attr.Name != null ? attr.Name : field.Name);
                    object value         = field.GetValue(this);
                    bool   is_null       = value == null;
                    Type   type          = is_null ? null : value.GetType();
                    bool   is_value_type = !is_null && type.IsPrimitive;

                    IntPtr native_value = Marshal.AllocHGlobal(is_value_type ? Math.Max(8, Marshal.SizeOf(value)) : Marshal.SizeOf(typeof(IntPtr)));

                    if (is_null)
                    {
                        Marshal.WriteIntPtr(native_value, IntPtr.Zero);
                        ObjCMethods.object_setInstanceVariable(this.NativeObject, name, native_value);
                        Marshal.FreeHGlobal(native_value);
                    }
                    else if (is_value_type)
                    {
                        Marshal.WriteIntPtr(native_value, IntPtr.Zero);
                        Marshal.StructureToPtr(value, native_value, false);
                        ObjCMethods.object_setInstanceVariable(this.NativeObject, name, native_value);
                        Marshal.FreeHGlobal(native_value);
                    }
                    else if (value is Object)
                    {
                        Marshal.FreeHGlobal(native_value);
                        native_value = ((Object)value).NativeObject;
                        ObjCMethods.object_setInstanceVariable(this.NativeObject, name, native_value);
                    }
                    else
                    {
                        throw new ArgumentException("Unhandled exporting of {0}" + value.GetType());
                    }
                }
            }
        }
        public static ObjCClass FromType(Type type)
        {
            if (type == null)
            {
                throw new ArgumentException();
            }

            if (objc_classes [type] != null)
            {
                return((ObjCClass)objc_classes [type]);
            }

            FieldInfo class_name = type.GetField("ObjectiveCName", BindingFlags.DeclaredOnly | BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.Static);
            FieldInfo base_name  = type.BaseType.GetField("ObjectiveCName", BindingFlags.DeclaredOnly | BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.Static);

            string cls_name   = type.Name;
            string super_name = type.BaseType.Name;

            if (class_name != null)
            {
                cls_name = (string)class_name.GetValue(type);
            }

            RegisterAttribute attr = (RegisterAttribute)Attribute.GetCustomAttribute(type, typeof(RegisterAttribute));

            if (attr != null)
            {
                cls_name = attr.Name;
            }

            IntPtr this_ptr = ObjCMethods.objc_lookUpClass(cls_name);

            if (this_ptr != IntPtr.Zero)
            {
                return(new ObjCClass((objc_class)Marshal.PtrToStructure(this_ptr, typeof(objc_class)), this_ptr));
            }

            if (base_name != null)
            {
                super_name = (string)base_name.GetValue(type.BaseType);
            }

            if (super_name == "CSObject" || super_name == "Object")
            {
                super_name = "NSObject";
            }

            if (cls_name == "CSThread")
            {
                super_name = "NSThread";
            }

            IntPtr super_ptr = ObjCMethods.objc_getClass(super_name);

            if (super_ptr == IntPtr.Zero)
            {
                return(null);
            }

            objc_class super_class = (objc_class)Marshal.PtrToStructure(super_ptr, typeof(objc_class));

            objc_class root_class = RootClass(super_class);
            objc_class objc_class = new objc_class();
            objc_class meta_class = new objc_class();

            // setup the meta class
            meta_class.isa           = root_class.isa;
            meta_class.super_class   = super_class.isa;
            meta_class.instance_size = ((objc_class)Marshal.PtrToStructure(super_class.isa, typeof(objc_class))).instance_size;
            meta_class.name          = Marshal.StringToHGlobalAnsi(cls_name);
            meta_class.info          = 2;
            meta_class.methodLists   = Marshal.AllocHGlobal(Marshal.SizeOf(typeof(IntPtr)));
            Marshal.WriteIntPtr(meta_class.methodLists, (IntPtr)(-1));

            IntPtr meta_class_ptr = Marshal.AllocHGlobal(Marshal.SizeOf(objc_class));

            Marshal.StructureToPtr(meta_class, meta_class_ptr, true);

            // setup the class
            objc_class.isa         = meta_class_ptr;
            objc_class.name        = meta_class.name;
            objc_class.info        = 1;
            objc_class.super_class = super_ptr;
            objc_class.methodLists = Marshal.AllocHGlobal(Marshal.SizeOf(typeof(IntPtr)));
            Marshal.WriteIntPtr(objc_class.methodLists, (IntPtr)(-1));

            // Add the ivars
            ArrayList ivars = new ArrayList();

            foreach (FieldInfo field in type.GetFields(BindingFlags.DeclaredOnly | BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance))
            {
                ConnectAttribute cattr = (ConnectAttribute)Attribute.GetCustomAttribute(field, typeof(ConnectAttribute));
                if (cattr != null)
                {
                    ivars.Add(field);
                }
            }
            if (ivars.Count > 0)
            {
                objc_ivar_list ivar_list = new objc_ivar_list();
                ivar_list.count = ivars.Count;

                IntPtr ivar_list_ptr = Marshal.AllocHGlobal(Marshal.SizeOf(typeof(objc_ivar_list)) + (ivars.Count * Marshal.SizeOf(typeof(objc_method))));
                int    ivar_offset   = super_class.instance_size;
                for (int i = 0; i < ivars.Count; i++)
                {
                    ConnectAttribute cattr = (ConnectAttribute)Attribute.GetCustomAttribute((FieldInfo)ivars [i], typeof(ConnectAttribute));
                    objc_ivar        ivar  = new objc_ivar();
                    int ivar_size          = cattr.Size;
                    ivar.ivar_name   = Marshal.StringToHGlobalAnsi(cattr.Name != null ? cattr.Name : ((FieldInfo)ivars [i]).Name);
                    ivar.ivar_type   = Marshal.StringToHGlobalAnsi(cattr.Type != null ? cattr.Type : ObjCTypes.FromType(((FieldInfo)ivars [i]).FieldType, out ivar_size));
                    ivar.ivar_offset = ivar_offset;
                    ivar_offset     += ivar_size;

                    Marshal.StructureToPtr(ivar, (IntPtr)((long)ivar_list_ptr + Marshal.SizeOf(typeof(objc_ivar_list)) + (i * Marshal.SizeOf(typeof(objc_ivar)))), true);
                }

                Marshal.StructureToPtr(ivar_list, ivar_list_ptr, false);
                objc_class.instance_size = ivar_offset;
                objc_class.ivars         = ivar_list_ptr;
            }
            else
            {
                objc_class.instance_size = super_class.instance_size;
            }

            // Register the class
            IntPtr objc_class_ptr = Marshal.AllocHGlobal(Marshal.SizeOf(objc_class));

            Marshal.StructureToPtr(objc_class, objc_class_ptr, true);
            ObjCMethods.objc_addClass(objc_class_ptr);

            // Add the methods
            objc_method_list method_list = new objc_method_list();
            ArrayList        methods     = new ArrayList();

            foreach (MethodInfo method in type.GetMethods(BindingFlags.DeclaredOnly | BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance))
            {
                if (type.Namespace != "Cocoa")
                {
                    ExportAttribute eattr = (ExportAttribute)Attribute.GetCustomAttribute(method, typeof(ExportAttribute));
                    if (eattr != null)
                    {
                        methods.Add(ObjCMethod.FromMethodInfo(method));
                    }
                }
                else
                {
                    methods.Add(ObjCMethod.FromMethodInfo(method));
                }
            }
// FIXME
//			foreach (ConstructorInfo constructor in type.GetConstructors (BindingFlags.DeclaredOnly | BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Static | BindingFlags.Instance))
//				methods.Add (ObjCMethod.FromConstructorInfo (constructor));

            method_list.count = methods.Count;

            IntPtr method_list_ptr = Marshal.AllocHGlobal(Marshal.SizeOf(typeof(objc_method_list)) + (methods.Count * Marshal.SizeOf(typeof(objc_method))));

            Marshal.StructureToPtr(method_list, method_list_ptr, false);

            for (int i = 0; i < methods.Count; i++)
            {
                Marshal.StructureToPtr((objc_method)methods [i], (IntPtr)((long)method_list_ptr + Marshal.SizeOf(typeof(objc_method_list)) + (i * Marshal.SizeOf(typeof(objc_method)))), true);
            }

            ObjCMethods.class_addMethods(objc_class_ptr, method_list_ptr);

            // Add the static methods
            method_list = new objc_method_list();
            methods     = new ArrayList();
            foreach (MethodInfo method in type.GetMethods(BindingFlags.DeclaredOnly | BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Static))
            {
                if (type.Namespace != "Cocoa")
                {
                    ExportAttribute eattr = (ExportAttribute)Attribute.GetCustomAttribute(method, typeof(ExportAttribute));
                    if (eattr != null)
                    {
                        methods.Add(ObjCMethod.FromMethodInfo(method));
                    }
                }
                else
                {
                    methods.Add(ObjCMethod.FromMethodInfo(method));
                }
            }

            method_list.count = methods.Count;

            IntPtr static_method_list_ptr = Marshal.AllocHGlobal(Marshal.SizeOf(typeof(objc_method_list)) + (methods.Count * Marshal.SizeOf(typeof(objc_method))));

            Marshal.StructureToPtr(method_list, static_method_list_ptr, false);

            for (int i = 0; i < methods.Count; i++)
            {
                Marshal.StructureToPtr((objc_method)methods [i], (IntPtr)((long)static_method_list_ptr + Marshal.SizeOf(typeof(objc_method_list)) + (i * Marshal.SizeOf(typeof(objc_method)))), true);
            }

            ObjCMethods.class_addMethods(meta_class_ptr, static_method_list_ptr);

            return(new ObjCClass(objc_class, objc_class_ptr));
        }