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 void Should_return_empty_string_from_new_argument_marshaller()
        {
            var stringArgumentMarshaller = new ArgumentMarshaller <string> {
                Value = string.Empty
            };

            Assert.That(stringArgumentMarshaller.Value, Is.EqualTo(string.Empty));
        }
Example #3
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 #4
0
 public UserDefinedMarshaller(Expression /*!*/ container, ArgumentMarshaller /*!*/ marshaller)
     : base(container)
 {
     _marshaller = marshaller;
 }
Example #5
0
 public UserDefinedMarshaller(Expression/*!*/ container, ArgumentMarshaller/*!*/ marshaller)
     : base(container) {
     _marshaller = marshaller;
 }
Example #6
0
                private static SignatureHelper GetCalliSignature(CallingConvention convention, ArgumentMarshaller/*!*/[] sig, Type calliRetType) {
                    SignatureHelper signature = SignatureHelper.GetMethodSigHelper(convention, calliRetType);
                    
                    foreach (ArgumentMarshaller argMarshaller in sig) {
                        signature.AddArgument(argMarshaller.NativeType);
                    }

                    return signature;
                }
Example #7
0
                /// <summary>
                /// Creates a method for calling with the specified signature.  The returned method has a signature
                /// of the form:
                /// 
                /// (IntPtr funcAddress, arg0, arg1, ..., object[] constantPool)
                /// 
                /// where IntPtr is the address of the function to be called.  The arguments types are based upon
                /// the types that the ArgumentMarshaller requires.
                /// </summary>
                private static MethodInfo/*!*/ CreateInteropInvoker(CallingConvention convention, ArgumentMarshaller/*!*/[]/*!*/ sig, INativeType nativeRetType, bool retVoid, List<object> constantPool) {
                    Type[] sigTypes = new Type[sig.Length + 2];
                    sigTypes[0] = typeof(IntPtr);
                    for (int i = 0; i < sig.Length; i++) {
                        sigTypes[i + 1] = sig[i].ArgumentExpression.Type;
                    }
                    sigTypes[sigTypes.Length - 1] = typeof(object[]);

                    Type retType = retVoid ? typeof(void) :
                        nativeRetType != null ? nativeRetType.GetPythonType() : typeof(int);
                    Type calliRetType = retVoid ? typeof(void) :
                                   nativeRetType != null ? nativeRetType.GetNativeType() : typeof(int);

#if !CTYPES_USE_SNIPPETS
                    DynamicMethod dm = new DynamicMethod("InteropInvoker", retType, sigTypes, DynamicModule);
#else
                    TypeGen tg = Snippets.Shared.DefineType("InteropInvoker", typeof(object), false, false);
                    MethodBuilder dm = tg.TypeBuilder.DefineMethod("InteropInvoker", CompilerHelpers.PublicStatic, retType, sigTypes);
#endif

                    ILGenerator method = dm.GetILGenerator();
                    LocalBuilder calliRetTmp = null, finalRetValue = null;
                    if (dm.ReturnType != typeof(void)) {
                        calliRetTmp = method.DeclareLocal(calliRetType);
                        finalRetValue = method.DeclareLocal(dm.ReturnType);
                    }

                    // try {
                    // emit all of the arguments, save their cleanups

                    method.BeginExceptionBlock();

                    List<MarshalCleanup> cleanups = null;
                    for (int i = 0; i < sig.Length; i++) {
#if DEBUG
                        method.Emit(OpCodes.Ldstr, String.Format("Argument #{0}, Marshaller: {1}, Native Type: {2}", i, sig[i], sig[i].NativeType));
                        method.Emit(OpCodes.Pop);
#endif
                        MarshalCleanup cleanup = sig[i].EmitCallStubArgument(method, i + 1, constantPool, sigTypes.Length - 1);
                        if (cleanup != null) {
                            if (cleanups == null) {
                                cleanups = new List<MarshalCleanup>();
                            }

                            cleanups.Add(cleanup);
                        }
                    }

                    // emit the target function pointer and the calli
#if DEBUG
                    method.Emit(OpCodes.Ldstr, "!!! CALLI !!!");
                    method.Emit(OpCodes.Pop);
#endif

                    method.Emit(OpCodes.Ldarg_0);
                    method.Emit(OpCodes.Calli, GetCalliSignature(convention, sig, calliRetType));

                    // if we have a return value we need to store it and marshal to Python
                    // before we run any cleanup code.
                    if (retType != typeof(void)) {
#if DEBUG
                        method.Emit(OpCodes.Ldstr, "!!! Return !!!");
                        method.Emit(OpCodes.Pop);
#endif

                        if (nativeRetType != null) {
                            method.Emit(OpCodes.Stloc, calliRetTmp);
                            nativeRetType.EmitReverseMarshalling(method, new Local(calliRetTmp), constantPool, sig.Length + 1);
                            method.Emit(OpCodes.Stloc, finalRetValue);
                        } else {
                            Debug.Assert(retType == typeof(int));
                            // no marshalling necessary
                            method.Emit(OpCodes.Stloc, finalRetValue);
                        }
                    }

                    // } finally { 
                    // emit the cleanup code

                    method.BeginFinallyBlock();

                    if (cleanups != null) {
                        foreach (MarshalCleanup mc in cleanups) {
                            mc.Cleanup(method);
                        }
                    }

                    method.EndExceptionBlock();

                    // }
                    // load the temporary value and return it.
                    if (retType != typeof(void)) {
                        method.Emit(OpCodes.Ldloc, finalRetValue);
                    }

                    method.Emit(OpCodes.Ret);

#if CTYPES_USE_SNIPPETS
                    return tg.TypeBuilder.CreateType().GetMethod("InteropInvoker");
#else
                    return dm;
#endif
                }
Example #8
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 #9
0
                private Expression MakeCall(ArgumentMarshaller[] signature, INativeType nativeRetType, bool retVoid) {
                    List<object> constantPool = new List<object>();
                    MethodInfo interopInvoker = CreateInteropInvoker(
                        GetCallingConvention(),
                        signature,
                        nativeRetType,
                        retVoid,
                        constantPool
                    );

                    // build the args - IntPtr, user Args, constant pool
                    Expression[] callArgs = new Expression[signature.Length + 2];
                    callArgs[0] = Expression.Property(
                        Expression.Convert(Expression, typeof(_CFuncPtr)),
                        "addr"
                    );
                    for (int i = 0; i < signature.Length; i++) {
                        callArgs[i + 1] = signature[i].ArgumentExpression;
                    }

                    callArgs[callArgs.Length - 1] = Expression.Constant(constantPool.ToArray());

                    return Expression.Call(interopInvoker, callArgs);
                }
Example #10
0
 /// <summary>
 /// we need to keep alive any methods which have arguments for the duration of the
 /// call.  Otherwise they could be collected on the finalizer thread before we come back.
 /// </summary>
 private void AddKeepAlives(ArgumentMarshaller[] signature, List<Expression> block) {
     foreach (ArgumentMarshaller marshaller in signature) {
         Expression keepAlive = marshaller.GetKeepAlive();
         if (keepAlive != null) {
             block.Add(keepAlive);
         }
     }
 }
Example #11
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;
                }