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