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); }
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); }
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)); }
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); }
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); }
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; }
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)); }