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