Пример #1
0
 public PInvokeMethodData(MethodDesc method, PInvokeILEmitterConfiguration config, MarshalDirection direction)
 {
     TargetMethod = method;
     PInvokeILEmitterConfiguration = config;
     Context        = method.Context;
     ImportMetadata = method.GetPInvokeMethodMetadata();
     Direction      = direction;
 }
Пример #2
0
        protected override void EmitElementCount(ILCodeStream codeStream, MarshalDirection direction)
        {
            ILEmitter emitter = _ilCodeStreams.Emitter;

            if (MarshalAsDescriptor == null || !MarshalAsDescriptor.SizeConst.HasValue)
            {
                throw new InvalidProgramException("SizeConst is required for ByValArray.");
            }

            if (direction == MarshalDirection.Forward)
            {
                // In forward direction ElementCount = Min(managed.length, SizeConst);

                var vLength  = emitter.NewLocal(Context.GetWellKnownType(WellKnownType.Int32));
                var lSmaller = emitter.NewCodeLabel();
                var lDone    = emitter.NewCodeLabel();

                codeStream.EmitLdArg(0);
                codeStream.Emit(ILOpcode.ldfld, emitter.NewToken(_managedField));

                var lNullCheck = emitter.NewCodeLabel();
                codeStream.Emit(ILOpcode.brfalse, lNullCheck);

                codeStream.EmitLdArg(0);
                codeStream.Emit(ILOpcode.ldfld, emitter.NewToken(_managedField));

                codeStream.Emit(ILOpcode.ldlen);
                codeStream.Emit(ILOpcode.conv_i4);
                codeStream.EmitStLoc(vLength);

                codeStream.EmitLabel(lNullCheck);

                Debug.Assert(MarshalAsDescriptor.SizeConst.HasValue);
                int sizeConst = (int)MarshalAsDescriptor.SizeConst.Value;

                codeStream.EmitLdc(sizeConst);
                codeStream.EmitLdLoc(vLength);
                codeStream.Emit(ILOpcode.blt, lSmaller);

                codeStream.EmitLdLoc(vLength);
                codeStream.Emit(ILOpcode.br, lDone);

                codeStream.EmitLabel(lSmaller);
                codeStream.EmitLdc(sizeConst);

                codeStream.EmitLabel(lDone);
            }
            else
            {
                // In reverse direction ElementCount = SizeConst;
                Debug.Assert(MarshalAsDescriptor.SizeConst.HasValue);
                int sizeConst = (int)MarshalAsDescriptor.SizeConst.Value;

                codeStream.EmitLdc(sizeConst);
            }
        }
Пример #3
0
        protected override void EmitElementCount(ILCodeStream codeStream, MarshalDirection direction)
        {
            ILEmitter emitter = _ilCodeStreams.Emitter;

            if (MarshalAsDescriptor == null || !MarshalAsDescriptor.SizeConst.HasValue)
            {
                throw new InvalidProgramException("SizeConst is required for ByValString.");
            }
            codeStream.EmitLdc((int)MarshalAsDescriptor.SizeConst.Value);
        }
Пример #4
0
        private static                                 Marshaller[] InitializeMarshallers(MethodDesc targetMethod, InteropStateManager interopStateManager, PInvokeFlags flags)
        {
            bool             isDelegate = targetMethod is DelegateMarshallingMethodThunk;
            MethodSignature  methodSig  = isDelegate ? ((DelegateMarshallingMethodThunk)targetMethod).DelegateSignature : targetMethod.Signature;
            MarshalDirection direction  = isDelegate ? ((DelegateMarshallingMethodThunk)targetMethod).Direction: MarshalDirection.Forward;
            int indexOffset             = 0;

            if (!methodSig.IsStatic && direction == MarshalDirection.Forward)
            {
                // For instance methods(eg. Forward delegate marshalling thunk), first argument is
                // the instance
                indexOffset = 1;
            }
            ParameterMetadata[] parameterMetadataArray = targetMethod.GetParameterMetadata();
            Marshaller[]        marshallers            = new Marshaller[methodSig.Length + 1];
            int parameterIndex = 0;
            ParameterMetadata parameterMetadata;

            for (int i = 0; i < marshallers.Length; i++)
            {
                Debug.Assert(parameterIndex == parameterMetadataArray.Length || i <= parameterMetadataArray[parameterIndex].Index);
                if (parameterIndex == parameterMetadataArray.Length || i < parameterMetadataArray[parameterIndex].Index)
                {
                    // if we don't have metadata for the parameter, create a dummy one
                    parameterMetadata = new ParameterMetadata(i, ParameterMetadataAttributes.None, null);
                }
                else
                {
                    Debug.Assert(i == parameterMetadataArray[parameterIndex].Index);
                    parameterMetadata = parameterMetadataArray[parameterIndex++];
                }
                TypeDesc parameterType = (i == 0) ? methodSig.ReturnType : methodSig[i - 1];  //first item is the return type
                marshallers[i] = Marshaller.CreateMarshaller(parameterType,
                                                             MarshallerType.Argument,
                                                             parameterMetadata.MarshalAsDescriptor,
                                                             direction,
                                                             marshallers,
                                                             interopStateManager,
                                                             indexOffset + parameterMetadata.Index,
                                                             flags,
                                                             parameterMetadata.In,
                                                             parameterMetadata.Out,
                                                             parameterMetadata.Return
                                                             );
            }

            return(marshallers);
        }
Пример #5
0
        public static Marshaller[] GetMarshallersForMethod(MethodDesc targetMethod)
        {
            Debug.Assert(targetMethod.IsPInvoke);

            MarshalDirection direction = MarshalDirection.Forward;
            MethodSignature  methodSig = targetMethod.Signature;
            PInvokeFlags     flags     = targetMethod.GetPInvokeMethodMetadata().Flags;

            ParameterMetadata[] parameterMetadataArray = targetMethod.GetParameterMetadata();
            Marshaller[]        marshallers            = new Marshaller[methodSig.Length + 1];
            ParameterMetadata   parameterMetadata;

            for (int i = 0, parameterIndex = 0; i < marshallers.Length; i++)
            {
                Debug.Assert(parameterIndex == parameterMetadataArray.Length || i <= parameterMetadataArray[parameterIndex].Index);
                if (parameterIndex == parameterMetadataArray.Length || i < parameterMetadataArray[parameterIndex].Index)
                {
                    // if we don't have metadata for the parameter, create a dummy one
                    parameterMetadata = new ParameterMetadata(i, ParameterMetadataAttributes.None, null);
                }
                else
                {
                    Debug.Assert(i == parameterMetadataArray[parameterIndex].Index);
                    parameterMetadata = parameterMetadataArray[parameterIndex++];
                }

                TypeDesc parameterType = (i == 0) ? methodSig.ReturnType : methodSig[i - 1];  //first item is the return type
                marshallers[i] = CreateMarshaller(parameterType,
                                                  parameterIndex,
                                                  methodSig.GetEmbeddedSignatureData(),
                                                  MarshallerType.Argument,
                                                  parameterMetadata.MarshalAsDescriptor,
                                                  direction,
                                                  marshallers,
                                                  parameterMetadata.Index,
                                                  flags,
                                                  parameterMetadata.In,
                                                  parameterMetadata.Out,
                                                  parameterMetadata.Return);
            }

            return(marshallers);
        }
Пример #6
0
        private static                                 Marshaller[] InitializeMarshallers(MethodDesc targetMethod, InteropStateManager interopStateManager, PInvokeFlags flags)
        {
            MarshalDirection direction = MarshalDirection.Forward;
            MethodSignature  methodSig;

            switch (targetMethod)
            {
            case DelegateMarshallingMethodThunk delegateMethod:
                methodSig = delegateMethod.DelegateSignature;
                direction = delegateMethod.Direction;
                break;

            case CalliMarshallingMethodThunk calliMethod:
                methodSig = calliMethod.TargetSignature;
                break;

            default:
                methodSig = targetMethod.Signature;
                break;
            }
            int indexOffset = 0;

            if (!methodSig.IsStatic && direction == MarshalDirection.Forward)
            {
                // For instance methods(eg. Forward delegate marshalling thunk), first argument is
                // the instance
                indexOffset = 1;
            }
            ParameterMetadata[] parameterMetadataArray = targetMethod.GetParameterMetadata();
            Marshaller[]        marshallers            = new Marshaller[methodSig.Length + 1];
            int parameterIndex = 0;
            ParameterMetadata parameterMetadata;

            for (int i = 0; i < marshallers.Length; i++)
            {
                Debug.Assert(parameterIndex == parameterMetadataArray.Length || i <= parameterMetadataArray[parameterIndex].Index);
                if (parameterIndex == parameterMetadataArray.Length || i < parameterMetadataArray[parameterIndex].Index)
                {
                    // if we don't have metadata for the parameter, create a dummy one
                    parameterMetadata = new ParameterMetadata(i, ParameterMetadataAttributes.None, null);
                }
                else
                {
                    Debug.Assert(i == parameterMetadataArray[parameterIndex].Index);
                    parameterMetadata = parameterMetadataArray[parameterIndex++];
                }

                TypeDesc parameterType;
                bool     isHRSwappedRetVal = false;
                if (i == 0)
                {
                    // First item is the return type
                    parameterType = methodSig.ReturnType;
                    if (!flags.PreserveSig && !parameterType.IsVoid)
                    {
                        // PreserveSig = false can only show up an regular forward PInvokes
                        Debug.Assert(direction == MarshalDirection.Forward);

                        parameterType     = methodSig.Context.GetByRefType(parameterType);
                        isHRSwappedRetVal = true;
                    }
                }
                else
                {
                    parameterType = methodSig[i - 1];
                }

                marshallers[i] = Marshaller.CreateMarshaller(parameterType,
                                                             parameterIndex,
                                                             methodSig.GetEmbeddedSignatureData(),
                                                             MarshallerType.Argument,
                                                             parameterMetadata.MarshalAsDescriptor,
                                                             direction,
                                                             marshallers,
                                                             interopStateManager,
                                                             indexOffset + parameterMetadata.Index,
                                                             flags,
                                                             parameterMetadata.In,
                                                             isHRSwappedRetVal ? true : parameterMetadata.Out,
                                                             isHRSwappedRetVal ? false : parameterMetadata.Return
                                                             );
            }

            return(marshallers);
        }
Пример #7
0
 /// <summary>
 /// Initializes a new instance of the <see cref="TelldusUtf8Marshaler"/> class.
 /// </summary>
 /// <param name="direction">
 /// if set to <c>Out</c> the marshaler will free strings using Telldus API.
 /// Use this for marshalers that receive strings from the API. If <c>In</c> the
 /// strings will be converted to native pointers. Use this for parameters to TelldusCore.
 /// </param>
 public TelldusUtf8Marshaler(MarshalDirection direction)
 {
     this.direction = direction;
 }