Beispiel #1
0
        private static IntPtr DoCreateBuffer(string encoding)
        {
            IntPtr buffer;

            switch (encoding)
            {
            case "c":
            case "C":
                buffer = Marshal.AllocHGlobal(4);                               // note that libffi expects buffers to be at least as big as a word
                break;

            case "s":
            case "S":
                buffer = Marshal.AllocHGlobal(4);
                break;

            case "i":
            case "I":
            case "l":
            case "L":
                buffer = Marshal.AllocHGlobal(4);
                break;

            case "q":
            case "Q":
                buffer = Marshal.AllocHGlobal(8);
                break;

            case "f":
                buffer = Marshal.AllocHGlobal(Marshal.SizeOf(typeof(float)));
                break;

            case "d":
                buffer = Marshal.AllocHGlobal(Marshal.SizeOf(typeof(double)));
                break;

            case "v":
            case "Vv":
                buffer = IntPtr.Zero;
                break;

            case "@":
            case "@?":
            case "#":
            case ":":
                buffer = Marshal.AllocHGlobal(Marshal.SizeOf(typeof(IntPtr)));
                break;

            default:
                char type = DoGetEncodingType(encoding);
                if (type == '^' || type == '*' || type == '[' || type == '(')                           // xxx*, char*, array, union
                {
                    buffer = Marshal.AllocHGlobal(Marshal.SizeOf(typeof(IntPtr)));
                }
                else if (type == '{')
                {
                    int i = encoding.IndexOf('=');
                    if (i >= 0)
                    {
                        string sname = encoding.Substring(1, i - 1);
                        Type   stype;
                        if (TypeEncoder.TryGetStruct(sname, out stype))
                        {
                            int bytes = Marshal.SizeOf(stype);
                            buffer = Marshal.AllocHGlobal(bytes);
                        }
                        else
                        {
                            throw new InvalidCallException("Don't know how to marshal " + sname + " to a native type. Is it marked with RegisterAttribute?");
                        }
                    }
                    else
                    {
                        throw new InvalidCallException("'" + encoding + "' doesn't have a struct name.");
                    }
                }
                else
                {
                    throw new InvalidCallException("Don't know how to marshal " + encoding + " to a native type.");
                }
                break;
            }

            return(buffer);
        }
Beispiel #2
0
        // Return an ffi_type* which will be used when values of the encoding
        // type are marshaled through libffi.
        public static IntPtr GetFfiType(Type type)
        {
            string encoding = TypeEncoder.Encode(type);

            return(DoGetFfiType(encoding));
        }