Beispiel #1
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);
            }
        }
Beispiel #2
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);
        }
Beispiel #3
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);
        }