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

            switch (targetMethod)
            {
            case DelegateMarshallingMethodThunk delegateMethod:
                methodSig = delegateMethod.DelegateSignature;
                direction = delegateMethod.Direction;
                runtimeMarshallingEnabled = MarshalHelpers.IsRuntimeMarshallingEnabled(delegateMethod.DelegateType.Module);
                break;

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

            default:
                methodSig = targetMethod.Signature;
                runtimeMarshallingEnabled = MarshalHelpers.IsRuntimeMarshallingEnabled(((MetadataType)targetMethod.OwningType).Module);
                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];
                }

                if (runtimeMarshallingEnabled)
                {
                    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
                                                                 );
                }
                else
                {
                    marshallers[i] = Marshaller.CreateDisabledMarshaller(
                        parameterType,
                        parameterIndex,
                        MarshallerType.Argument,
                        direction,
                        marshallers,
                        indexOffset + parameterMetadata.Index,
                        flags,
                        parameterMetadata.Return);
                }
            }

            return(marshallers);
        }