Example #1
0
                private ArgumentMarshaller /*!*/[] /*!*/ GetArgumentMarshallers(DynamicMetaObject /*!*/[] /*!*/ args)
                {
                    CFuncPtrType funcType = ((CFuncPtrType)Value.NativeType);

                    ArgumentMarshaller[] res = new ArgumentMarshaller[args.Length];


                    // first arg is taken by self if we're a com method
                    for (int i = 0; i < args.Length; i++)
                    {
                        DynamicMetaObject mo      = args[i];
                        object            argType = null;
                        if (Value._comInterfaceIndex == -1 || i != 0)
                        {
                            int argtypeIndex = Value._comInterfaceIndex == -1 ? i : i - 1;

                            if (Value._argtypes != null && argtypeIndex < Value._argtypes.Count)
                            {
                                argType = Value._argtypes[argtypeIndex];
                            }
                            else if (funcType._argtypes != null && argtypeIndex < funcType._argtypes.Length)
                            {
                                argType = funcType._argtypes[argtypeIndex];
                            }
                        }

                        res[i] = GetMarshaller(mo.Expression, mo.Value, i, argType);
                    }
                    return(res);
                }
Example #2
0
            public _CFuncPtr(CodeContext context, object function)
            {
                _memHolder = new MemoryHolder(IntPtr.Size);
                if (function != null)
                {
                    if (!PythonOps.IsCallable(context, function))
                    {
                        throw PythonOps.TypeError("argument must be called or address of function");
                    }

                    _delegate = ((CFuncPtrType)DynamicHelpers.GetPythonType(this)).MakeReverseDelegate(context, function);
                    addr      = Marshal.GetFunctionPointerForDelegate(_delegate);

                    CFuncPtrType myType  = (CFuncPtrType)NativeType;
                    PythonType   resType = myType._restype;
                    if (resType != null)
                    {
                        if (!(resType is INativeType) || resType is PointerType)
                        {
                            throw PythonOps.TypeError($"invalid result type {resType.Name} for callback function");
                        }
                    }
                }
                _id = Interlocked.Increment(ref _curId);
            }
Example #3
0
        public static object call_function(CodeContext context, IntPtr address, PythonTuple args)
        {
            CFuncPtrType funcType = GetFunctionType(context, FUNCFLAG_STDCALL);

            _CFuncPtr func = (_CFuncPtr)funcType.CreateInstance(context, address);

            return(PythonOps.CallWithArgsTuple(func, new object[0], args));
        }
Example #4
0
        private static CFuncPtrType GetFunctionType(CodeContext context, int flags)
        {
            // Ideally we should cache these...
            SimpleType resType = new SimpleType(
                context,
                "int",
                PythonTuple.MakeTuple(DynamicHelpers.GetPythonTypeFromType(typeof(SimpleCData))), PythonOps.MakeHomogeneousDictFromItems(new object[] { "i", "_type_" }));

            CFuncPtrType funcType = new CFuncPtrType(
                context,
                "func",
                PythonTuple.MakeTuple(DynamicHelpers.GetPythonTypeFromType(typeof(_CFuncPtr))),
                PythonOps.MakeHomogeneousDictFromItems(new object[] { FUNCFLAG_STDCALL, "_flags_", resType, "_restype_" }));

            return(funcType);
        }
Example #5
0
                private ArgumentMarshaller /*!*/[] /*!*/ GetArgumentMarshallers(DynamicMetaObject /*!*/[] /*!*/ args)
                {
                    CFuncPtrType funcType = ((CFuncPtrType)Value.NativeType);

                    ArgumentMarshaller[] res = new ArgumentMarshaller[args.Length];
                    for (int i = 0; i < args.Length; i++)
                    {
                        DynamicMetaObject mo      = args[i];
                        object            argType = null;
                        if (Value._argtypes != null && i < Value._argtypes.Count)
                        {
                            argType = Value._argtypes[i];
                        }
                        else if (funcType._argtypes != null && i < funcType._argtypes.Length)
                        {
                            argType = funcType._argtypes[i];
                        }

                        res[i] = GetMarshaller(mo.Expression, mo.Value, i, argType);
                    }
                    return(res);
                }
Example #6
0
        private static CFuncPtrType GetFunctionType(CodeContext context, int flags) {
            // Ideally we should cache these...
            SimpleType resType = new SimpleType(
                context,
                "int",
                PythonTuple.MakeTuple(DynamicHelpers.GetPythonTypeFromType(typeof(SimpleCData))), PythonOps.MakeHomogeneousDictFromItems(new object[] { "i", "_type_" }));

            CFuncPtrType funcType = new CFuncPtrType(
                context,
                "func",
                PythonTuple.MakeTuple(DynamicHelpers.GetPythonTypeFromType(typeof(_CFuncPtr))),
                PythonOps.MakeHomogeneousDictFromItems(new object[] { FUNCFLAG_STDCALL, "_flags_", resType, "_restype_" }));
            return funcType;
        }
Example #7
0
                public override DynamicMetaObject BindInvoke(InvokeBinder binder, DynamicMetaObject[] args)
                {
                    CodeContext context = PythonContext.GetPythonContext(binder).SharedContext;

                    ArgumentMarshaller[] signature = GetArgumentMarshallers(args);

                    BindingRestrictions restrictions = BindingRestrictions.GetTypeRestriction(
                        Expression,
                        Value.GetType()
                        ).Merge(
                        BindingRestrictions.GetExpressionRestriction(
                            Expression.Call(
                                typeof(ModuleOps).GetMethod("CheckFunctionId"),
                                Expression.Convert(Expression, typeof(_CFuncPtr)),
                                Expression.Constant(Value.Id)
                                )
                            )
                        );

                    foreach (var arg in signature)
                    {
                        restrictions = restrictions.Merge(arg.GetRestrictions());
                    }

                    int argCount = args.Length;

                    if (Value._comInterfaceIndex != -1)
                    {
                        argCount--;
                    }
                    // need to verify we have the correct # of args
                    if (Value._argtypes != null)
                    {
                        if (argCount < Value._argtypes.Count || (Value.CallingConvention != CallingConvention.Cdecl && argCount > Value._argtypes.Count))
                        {
                            return(IncorrectArgCount(binder, restrictions, Value._argtypes.Count, argCount));
                        }
                    }
                    else
                    {
                        CFuncPtrType funcType = ((CFuncPtrType)Value.NativeType);
                        if (funcType._argtypes != null &&
                            (argCount < funcType._argtypes.Length || (Value.CallingConvention != CallingConvention.Cdecl && argCount > funcType._argtypes.Length)))
                        {
                            return(IncorrectArgCount(binder, restrictions, funcType._argtypes.Length, argCount));
                        }
                    }

                    if (Value._comInterfaceIndex != -1 && args.Length == 0)
                    {
                        return(NoThisParam(binder, restrictions));
                    }

                    Expression        call  = MakeCall(signature, GetNativeReturnType(), Value.Getrestype() == null, GetFunctionAddress(args));
                    List <Expression> block = new List <Expression>();
                    Expression        res;

                    if (call.Type != typeof(void))
                    {
                        ParameterExpression tmp = Expression.Parameter(call.Type, "ret");
                        block.Add(Expression.Assign(tmp, call));
                        AddKeepAlives(signature, block);
                        block.Add(tmp);
                        res = Expression.Block(new[] { tmp }, block);
                    }
                    else
                    {
                        block.Add(call);
                        AddKeepAlives(signature, block);
                        res = Expression.Block(block);
                    }

                    res = AddReturnChecks(context, args, res);

                    return(new DynamicMetaObject(Utils.Convert(res, typeof(object)), restrictions));
                }