Пример #1
0
        private void DoGetPropsString(StringBuilder builder)
        {
            Class klass = class_();

            while (klass != null && (IntPtr)klass != IntPtr.Zero)
            {
                int    count  = 0;
                IntPtr buffer = class_copyPropertyList((IntPtr)klass, ref count);

                if (count > 0)
                {
                    PtrArray ivars = new PtrArray(buffer, count);

                    for (int i = 0; i < count; ++i)
                    {
                        IntPtr name = property_getName(ivars[i]);                               // property_getAttributes?
                        string s    = Marshal.PtrToStringAnsi(name);
                        builder.AppendLine(s);
                    }
                }

                Marshal.FreeHGlobal(buffer);

                klass = klass.BaseClass;
            }
        }
Пример #2
0
        private void DoAddMethods(Class klass, List <List <string> > table, bool includePrivate)
        {
            int    count  = 0;
            IntPtr buffer = class_copyMethodList((IntPtr)klass, ref count);

            if (count > 0)
            {
                PtrArray methods = new PtrArray(buffer, count);

                for (int i = 0; i < count; ++i)
                {
                    Selector sel = new Selector(method_getName(methods[i]));
                    if (includePrivate || (sel.Name.Length > 0 && sel.Name[0] != '_'))
                    {
                        List <string> row = new List <string>();
                        row.Add(sel.Name);

                        IntPtr imp = method_getImplementation(methods[i]);
                        row.Add(imp.ToInt32().ToString("X"));

                        table.Add(row);
                    }
                }
            }

            Marshal.FreeHGlobal(buffer);
        }
Пример #3
0
        static OpaqueInt getItemAt(PtrArray <OpaqueInt> array, int index)
        {
            var dataPtr = Marshal.ReadIntPtr(array.Handle);
            var data    = Marshal.ReadIntPtr(dataPtr, IntPtr.Size * index);

            return(Opaque.GetInstance <OpaqueInt> (data, Transfer.None));
        }
Пример #4
0
        private void DoGetIvarString(StringBuilder builder, bool includePrivate)
        {
            Class klass = class_();

            while (klass != null && (IntPtr)klass != IntPtr.Zero)
            {
                int    count  = 0;
                IntPtr buffer = class_copyIvarList((IntPtr)klass, ref count);

                if (count > 0)
                {
                    PtrArray ivars = new PtrArray(buffer, count);

                    for (int i = 0; i < count; ++i)
                    {
                        IntPtr name = ivar_getName(ivars[i]);
                        string s    = Marshal.PtrToStringAnsi(name);
                        if (includePrivate || (s.Length > 0 && s[0] != '_'))
                        {
                            builder.AppendLine(s);
                        }
                    }
                }

                Marshal.FreeHGlobal(buffer);

                klass = klass.BaseClass;
            }
        }
Пример #5
0
        public void TestRemoveRange()
        {
            var a = new PtrArray <OpaqueInt> ();

            a.Add(_(1));
            a.Add(_(2));
            a.Add(_(3));
            a.Add(_(4));
            a.Add(_(5));
            a.Add(_(6));
            Assume.That(a.Count, Is.EqualTo(6));

            a.RemoveRange(0, 0);
            Assert.That(a.Count, Is.EqualTo(6));

            a.RemoveRange(1, 2);
            Assert.That(a.Count, Is.EqualTo(4));
            Assert.That(getItemAt(a, 0), Is.EqualTo(_(1)));
            Assert.That(getItemAt(a, 1), Is.EqualTo(_(4)));
            Assert.That(getItemAt(a, 2), Is.EqualTo(_(5)));
            Assert.That(getItemAt(a, 3), Is.EqualTo(_(6)));

            Assert.That(() => a.RemoveRange(-1, 0), Throws.TypeOf <ArgumentOutOfRangeException> ());
            Assert.That(() => a.RemoveRange(0, -1), Throws.TypeOf <ArgumentOutOfRangeException> ());
            Assert.That(() => a.RemoveRange(3, 4), Throws.TypeOf <ArgumentException> ());

            a.Dispose();
            Assert.That(() => a.RemoveRange(0, 0), Throws.TypeOf <ObjectDisposedException> ());

            Utility.AssertNoGLibLog();
        }
Пример #6
0
        // Call imp where args points to buffers containing the arguments and result
        // is a buffer where the result will be written.
        public static void Call(IntPtr cif, IntPtr imp, IntPtr result, PtrArray args)
        {
            IntPtr exception = IntPtr.Zero;

            FfiCall(cif, imp, result, args.ToIntPtr(), ref exception);

            if (exception != IntPtr.Zero)
            {
                CocoaException.Raise(exception);
            }
        }
Пример #7
0
        public void TestSetSize()
        {
            var a = new PtrArray <OpaqueInt> ();

            Assume.That(a.Count, Is.EqualTo(0));

            a.SetSize(5);
            Assert.That(a.Count, Is.EqualTo(5));

            a.Dispose();
            Assert.That(() => a.SetSize(0), Throws.TypeOf <ObjectDisposedException> ());

            Utility.AssertNoGLibLog();
        }
Пример #8
0
        private static IntPtr DoAllocStructFfiType(string sname, string pencoding)
        {
            List <IntPtr> fieldTypes = new List <IntPtr>();

            int index = 0;

            while (index < pencoding.Length)
            {
                if (pencoding[index] == '{')
                {
                    int    i          = pencoding.IndexOf('=', index);
                    int    j          = pencoding.IndexOf('}', index);
                    string sname2     = pencoding.Substring(index + 1, i - index - 1);
                    string pencoding2 = pencoding.Substring(i + 1, j - i - 1);
                    fieldTypes.Add(DoAllocStructFfiType(sname2, pencoding2));

                    index = j + 1;
                }
                else
                {
                    char code = DoGetCode(pencoding[index++].ToString());
                    if (code == '\x0')
                    {
                        throw new InvalidCallException("Can only marshal structs whose fields are primitive types or structs with primitive types and " + sname + " isn't.");
                    }

                    fieldTypes.Add(GetFfiType(code));
                }
            }

            fieldTypes.Add(IntPtr.Zero);

            // Note that we don't free these, but that should be OK since
            // there should only be a limited number of structs we marshal
            // and it doesn't hurt to cache the ffi_type* anyway.
            PtrArray ft = new PtrArray(fieldTypes.Count);

            for (int i = 0; i < ft.Length; ++i)
            {
                ft[i] = fieldTypes[i];
            }

            IntPtr result = AllocStructFfiType(ft.ToIntPtr());

            return(result);
        }
Пример #9
0
        // Use ffi_type*'s to create an ffi_cif*. Note that libffi will save the atypes
        // pointer so we can't free it (and we can't use an IntPtr[] without explicity
        // saving the array).
        public static IntPtr AllocCif(IntPtr rtype, PtrArray atypes)
        {
            if (atypes[atypes.Length - 1] != IntPtr.Zero)
            {
                throw new ArgumentException("atypes should be null terminated");
            }

            IntPtr cif = AllocCif(atypes.Length - 1, rtype, atypes.ToIntPtr());

            if (cif.ToInt32() == 1)
            {
                throw new ArgumentException("FFI_BAD_TYPEDEF");
            }
            else if (cif.ToInt32() == 2)
            {
                throw new ArgumentException("FFI_BAD_ABI");
            }

            return(cif);
        }
Пример #10
0
        private static IntPtr DoCreateCif(MethodInfo info)
        {
            IntPtr resultType = Ffi.GetFfiType(info.ReturnType);

            ParameterInfo[] parms   = info.GetParameters();
            int             numArgs = parms.Length;

            PtrArray argTypes = new PtrArray(numArgs + 3);

            argTypes[0] = Ffi.GetFfiType(typeof(NSObject));
            argTypes[1] = Ffi.GetFfiType(typeof(Selector));

            for (int i = 0; i < numArgs; ++i)
            {
                Type type = parms[i].ParameterType;
                argTypes[i + 2] = Ffi.GetFfiType(type);
            }

            argTypes[numArgs + 2] = IntPtr.Zero;

            return(Ffi.AllocCif(resultType, argTypes));                         // note that we don't want to free argTypes
        }
Пример #11
0
        public void TestSort()
        {
            var a = new PtrArray <OpaqueInt> ();

            a.Add(_(3));
            a.Add(_(1));
            a.Add(_(2));
            Assume.That(getItemAt(a, 0), Is.EqualTo(_(3)));
            Assume.That(getItemAt(a, 1), Is.EqualTo(_(1)));
            Assume.That(getItemAt(a, 2), Is.EqualTo(_(2)));

            a.Sort((x, y) => x.Value - y.Value);
            Assert.That(getItemAt(a, 0), Is.EqualTo(_(1)));
            Assert.That(getItemAt(a, 1), Is.EqualTo(_(2)));
            Assert.That(getItemAt(a, 2), Is.EqualTo(_(3)));

            Assert.That(() => a.Sort(null), Throws.TypeOf <ArgumentNullException> ());

            a.Dispose();
            Assert.That(() => a.Sort((x, y) => 0), Throws.TypeOf <ObjectDisposedException> ());

            Utility.AssertNoGLibLog();
        }
Пример #12
0
            public StackFrame(MethodSignature sig)
            {
                m_returnEncoding = sig.GetReturnEncoding();

                IntPtr resultType = Ffi.GetFfiType(m_returnEncoding);

                m_resultBuffer = Ffi.CreateBuffer(m_returnEncoding);

                int numArgs = sig.GetNumArgs();

                m_argBuffers = new PtrArray(numArgs);
                m_argTypes   = new PtrArray(numArgs + 1);

                for (int i = 0; i < numArgs; ++i)
                {
                    string encoding = sig.GetArgEncoding(i);
                    m_argBuffers[i] = Ffi.CreateBuffer(encoding);
                    m_argTypes[i]   = Ffi.GetFfiType(encoding);
                }

                m_argTypes[numArgs] = IntPtr.Zero;

                m_cif = Ffi.AllocCif(resultType, m_argTypes);
            }
Пример #13
0
        public void TestRemoveFast()
        {
            var a = new PtrArray <OpaqueInt> ();

            Assume.That(a.Count, Is.EqualTo(0));

            Assert.That(a.RemoveFast(_(0)), Is.False);
            Assert.That(a.Count, Is.EqualTo(0));

            a.Add(_(1));
            Assume.That(a.Count, Is.EqualTo(1));

            Assert.That(a.RemoveFast(_(0)), Is.False);
            Assert.That(a.Count, Is.EqualTo(1));
            Assert.That(a.RemoveFast(_(1)), Is.True);
            Assert.That(a.Count, Is.EqualTo(0));

            a.Add(_(1));
            a.Add(_(2));
            a.Add(_(3));
            a.Add(_(4));
            Assume.That(a.Count, Is.EqualTo(4));

            Assert.That(a.RemoveFast(_(0)), Is.False);
            Assert.That(a.Count, Is.EqualTo(4));
            Assert.That(a.RemoveFast(_(2)), Is.True);
            Assert.That(a.Count, Is.EqualTo(3));
            Assert.That(getItemAt(a, 0), Is.EqualTo(_(1)));
            Assert.That(getItemAt(a, 1), Is.EqualTo(_(4)));
            Assert.That(getItemAt(a, 2), Is.EqualTo(_(3)));

            a.Dispose();
            Assert.That(() => a.RemoveFast(_(0)), Throws.TypeOf <ObjectDisposedException> ());

            Utility.AssertNoGLibLog();
        }
Пример #14
0
        internal IntPtr Call(IntPtr dummy, IntPtr resultBuffer, IntPtr argBuffers)
        {
            Unused.Value = dummy;

            IntPtr exception = IntPtr.Zero;

            try
            {
                // Get the this pointer for the method we're calling.
                PtrArray argArray = new PtrArray(argBuffers, m_signature.GetNumArgs() + 2);
                NSObject instance = (NSObject)Ffi.DrainBuffer(argArray[0], "@");

                // Get the selector for the method that was called.
                // Get the method arguments.
                string   encoding;
                object[] args = new object[m_signature.GetNumArgs() - 2];
                for (int i = 0; i < args.Length; ++i)
                {
                    encoding = m_signature.GetArgEncoding(i + 2);
                    if (encoding == "@")
                    {
                        args[i] = (NSObject)Ffi.DrainBuffer(argArray[i + 2], encoding);
                    }
                    else
                    {
                        args[i] = Ffi.DrainBuffer(argArray[i + 2], encoding);
                    }

                    // Native code doesn't distinguish between unsigned short and unichar
                    // so we need to fix things up here.
                    Type ptype = m_info.GetParameters()[i].ParameterType;
                    if (ptype == typeof(char))
                    {
                        args[i] = (char)(UInt16)args[i];
                    }
                    else if (ptype != typeof(NSObject) && typeof(NSObject).IsAssignableFrom(ptype))
                    {
                        IntPtr ip = (IntPtr)(NSObject)args[i];

                        args[i] = NSObject.Lookup(ip);
                        if (args[i] == null && ip != IntPtr.Zero)
                        {
                            throw new InvalidCallException(string.Format("Couldn't create a {0} when calling {1}. Is {0} registered or exported?", ptype, m_info.Name));
                        }
                    }

                    // Provide a better error message than the uber lame: "parameters".
                    if (args[i] != null && !ptype.IsAssignableFrom(args[i].GetType()))
                    {
                        throw new InvalidCallException(string.Format("Expected a {0} when calling {1} but have a {2}.", ptype, m_info.Name, args[i].GetType()));
                    }
                }

                // Call the method,
                object value = m_info.Invoke(instance, args);

                // and marshal the result.
                encoding = m_signature.GetReturnEncoding();
                if (encoding == "c" || encoding == "C" || encoding == "s" || encoding == "S")                   // per 'man ffi_call' small results must be stuffed into "storage that is sizeof(long) or larger"
                {
                    int r = Convert.ToInt32(value);
                    Ffi.FillBuffer(resultBuffer, r, "l");
                }
                else if (encoding != "v" && encoding != "Vv")
                {
                    Ffi.FillBuffer(resultBuffer, value, encoding);
                }
            }
            catch (TargetInvocationException ie)
            {
                if (LogException != null)
                {
                    LogException(ie);
                }
                else
                {
                    DoLogException(ie);
                }
                exception = DoCreateNativeException(ie.InnerException);
            }
            catch (Exception e)
            {
                if (LogException != null)
                {
                    LogException(e);
                }
                else
                {
                    DoLogException(e);
                }
                exception = DoCreateNativeException(e);
            }

            return(exception);
        }