Пример #1
0
        protected override void EmitMarshalArgumentManagedToNative()
        {
            ILEmitter         emitter = _ilCodeStreams.Emitter;
            ILCodeStream      marshallingCodeStream   = _ilCodeStreams.MarshallingCodeStream;
            ILCodeStream      unmarshallingCodeStream = _ilCodeStreams.UnmarshallingCodestream;
            TypeSystemContext context = PInvokeMethodData.Context;
            // TODO: Handles [out] marshalling only for now

            var stringBuilderType = context.SystemModule.GetKnownType("System.Text", "StringBuilder");
            var charArrayType     = context.GetWellKnownType(WellKnownType.Char).MakeArrayType();

            IL.Stubs.ILLocalVariable vStringBuilder = emitter.NewLocal(stringBuilderType);
            IL.Stubs.ILLocalVariable vBuffer        = emitter.NewLocal(charArrayType);

            marshallingCodeStream.EmitStLoc(vStringBuilder);

            marshallingCodeStream.EmitLdLoc(vStringBuilder);
            marshallingCodeStream.Emit(ILOpcode.call, emitter.NewToken(
                                           context.GetHelperEntryPoint("InteropHelpers", "GetEmptyStringBuilderBuffer")));
            marshallingCodeStream.EmitStLoc(vBuffer);

            unmarshallingCodeStream.EmitLdLoc(vStringBuilder);
            unmarshallingCodeStream.EmitLdLoc(vBuffer);
            unmarshallingCodeStream.Emit(ILOpcode.call, emitter.NewToken(
                                             context.GetHelperEntryPoint("InteropHelpers", "ReplaceStringBuilderBuffer")));

            marshallingCodeStream.EmitLdLoc(vBuffer);
            ManagedParameterType = charArrayType;
            base.EmitMarshalArgumentManagedToNative();
        }
Пример #2
0
        protected override void EmitMarshalArgumentManagedToNative()
        {
            ILCodeStream marshallingCodeStream = _ilCodeStreams.MarshallingCodeStream;
            ILEmitter    emitter   = _ilCodeStreams.Emitter;
            var          arrayType = (ArrayType)ManagedParameterType;

            Debug.Assert(arrayType.IsSzArray);

            IL.Stubs.ILLocalVariable vPinnedFirstElement = emitter.NewLocal(arrayType.ParameterType.MakeByRefType(), true);
            IL.Stubs.ILLocalVariable vArray = emitter.NewLocal(arrayType);
            ILCodeLabel lNullArray          = emitter.NewCodeLabel();

            // Check for null array, or 0 element array.
            marshallingCodeStream.Emit(ILOpcode.dup);
            marshallingCodeStream.EmitStLoc(vArray);
            marshallingCodeStream.Emit(ILOpcode.brfalse, lNullArray);
            marshallingCodeStream.EmitLdLoc(vArray);
            marshallingCodeStream.Emit(ILOpcode.ldlen);
            marshallingCodeStream.Emit(ILOpcode.conv_i4);
            marshallingCodeStream.Emit(ILOpcode.brfalse, lNullArray);

            // Array has elements.
            marshallingCodeStream.EmitLdLoc(vArray);
            marshallingCodeStream.EmitLdc(0);
            marshallingCodeStream.Emit(ILOpcode.ldelema, emitter.NewToken(arrayType.ElementType));
            marshallingCodeStream.EmitStLoc(vPinnedFirstElement);

            // Fall through. If array didn't have elements, vPinnedFirstElement is zeroinit.
            marshallingCodeStream.EmitLabel(lNullArray);
            marshallingCodeStream.EmitLdLoc(vPinnedFirstElement);
            marshallingCodeStream.Emit(ILOpcode.conv_i);

            NativeParameterType = PInvokeMethodData.Context.GetWellKnownType(WellKnownType.IntPtr);
        }
Пример #3
0
        protected override void EmitMarshalArgumentManagedToNative()
        {
            ILEmitter         emitter = _ilCodeStreams.Emitter;
            ILCodeStream      marshallingCodeStream = _ilCodeStreams.MarshallingCodeStream;
            TypeSystemContext context = PInvokeMethodData.Context;
            //
            // Unicode marshalling. Pin the string and push a pointer to the first character on the stack.
            //

            TypeDesc stringType = context.GetWellKnownType(WellKnownType.String);

            IL.Stubs.ILLocalVariable vPinnedString = emitter.NewLocal(stringType, true);
            ILCodeLabel lNullString = emitter.NewCodeLabel();

            marshallingCodeStream.EmitStLoc(vPinnedString);
            marshallingCodeStream.EmitLdLoc(vPinnedString);

            marshallingCodeStream.Emit(ILOpcode.conv_i);
            marshallingCodeStream.Emit(ILOpcode.dup);

            // Marshalling a null string?
            marshallingCodeStream.Emit(ILOpcode.brfalse, lNullString);

            marshallingCodeStream.Emit(ILOpcode.call, emitter.NewToken(
                                           context.SystemModule.
                                           GetKnownType("System.Runtime.CompilerServices", "RuntimeHelpers").
                                           GetKnownMethod("get_OffsetToStringData", null)));

            marshallingCodeStream.Emit(ILOpcode.add);

            marshallingCodeStream.EmitLabel(lNullString);

            NativeParameterType = context.GetWellKnownType(WellKnownType.IntPtr);
        }
Пример #4
0
        protected override TypeDesc MarshalArgument(TypeDesc managedType, ILEmitter emitter, ILCodeStream marshallingCodeStream, ILCodeStream unmarshallingCodeStream)
        {
            TypeSystemContext context = PInvokeMethodData.Context;

            if (PInvokeMethodData.GetCharSet() == PInvokeAttributes.CharSetUnicode)
            {
                // TODO: Handles [out] marshalling only for now

                var stringBuilderType = context.SystemModule.GetKnownType("System.Text", "StringBuilder");
                var charArrayType     = context.GetWellKnownType(WellKnownType.Char).MakeArrayType();

                IL.Stubs.ILLocalVariable vStringBuilder = emitter.NewLocal(stringBuilderType);
                IL.Stubs.ILLocalVariable vBuffer        = emitter.NewLocal(charArrayType);

                marshallingCodeStream.EmitStLoc(vStringBuilder);

                marshallingCodeStream.EmitLdLoc(vStringBuilder);
                marshallingCodeStream.Emit(ILOpcode.call, emitter.NewToken(
                                               context.GetHelperEntryPoint("InteropHelpers", "GetEmptyStringBuilderBuffer")));
                marshallingCodeStream.EmitStLoc(vBuffer);

                unmarshallingCodeStream.EmitLdLoc(vStringBuilder);
                unmarshallingCodeStream.EmitLdLoc(vBuffer);
                unmarshallingCodeStream.Emit(ILOpcode.call, emitter.NewToken(
                                                 context.GetHelperEntryPoint("InteropHelpers", "ReplaceStringBuilderBuffer")));

                marshallingCodeStream.EmitLdLoc(vBuffer);
                return(base.MarshalArgument(charArrayType, emitter, marshallingCodeStream, unmarshallingCodeStream));
            }
            else
            {
                throw new NotSupportedException();
            }
        }
Пример #5
0
        protected override TypeDesc MarshalArgument(TypeDesc managedType, ILEmitter emitter, ILCodeStream marshallingCodeStream, ILCodeStream unmarshallingCodeStream)
        {
            var byRefType = (ByRefType)managedType;

            IL.Stubs.ILLocalVariable vPinnedByRef = emitter.NewLocal(byRefType, true);
            marshallingCodeStream.EmitStLoc(vPinnedByRef);
            marshallingCodeStream.EmitLdLoc(vPinnedByRef);
            marshallingCodeStream.Emit(ILOpcode.conv_i);

            return(PInvokeMethodData.Context.GetWellKnownType(WellKnownType.IntPtr));
        }
Пример #6
0
        protected virtual void EmitByRefManagedToNative()
        {
            ILCodeStream marshallingCodeStream = _ilCodeStreams.MarshallingCodeStream;
            ILEmitter    emitter   = _ilCodeStreams.Emitter;
            var          byRefType = (ByRefType)ManagedParameterType;

            IL.Stubs.ILLocalVariable vPinnedByRef = emitter.NewLocal(byRefType, true);
            marshallingCodeStream.EmitStLoc(vPinnedByRef);
            marshallingCodeStream.EmitLdLoc(vPinnedByRef);
            marshallingCodeStream.Emit(ILOpcode.conv_i);

            NativeParameterType = PInvokeMethodData.Context.GetWellKnownType(WellKnownType.IntPtr);
        }
Пример #7
0
        protected override TypeDesc MarshalArgument(TypeDesc managedType, ILEmitter emitter, ILCodeStream marshallingCodeStream, ILCodeStream unmarshallingCodeStream)
        {
            TypeSystemContext context = PInvokeMethodData.Context;

            if (PInvokeMethodData.GetCharSet() == PInvokeAttributes.CharSetUnicode)
            {
                //
                // Unicode marshalling. Pin the string and push a pointer to the first character on the stack.
                //

                TypeDesc stringType = context.GetWellKnownType(WellKnownType.String);

                IL.Stubs.ILLocalVariable vPinnedString = emitter.NewLocal(stringType, true);
                ILCodeLabel lNullString = emitter.NewCodeLabel();

                marshallingCodeStream.EmitStLoc(vPinnedString);
                marshallingCodeStream.EmitLdLoc(vPinnedString);

                marshallingCodeStream.Emit(ILOpcode.conv_i);
                marshallingCodeStream.Emit(ILOpcode.dup);

                // Marshalling a null string?
                marshallingCodeStream.Emit(ILOpcode.brfalse, lNullString);

                marshallingCodeStream.Emit(ILOpcode.call, emitter.NewToken(
                                               context.SystemModule.
                                               GetKnownType("System.Runtime.CompilerServices", "RuntimeHelpers").
                                               GetKnownMethod("get_OffsetToStringData", null)));

                marshallingCodeStream.Emit(ILOpcode.add);

                marshallingCodeStream.EmitLabel(lNullString);

                return(context.GetWellKnownType(WellKnownType.IntPtr));
            }
            else
            {
                //
                // ANSI marshalling. Allocate a byte array, copy characters, pin first element.
                //

                var stringToAnsi = context.GetHelperEntryPoint("InteropHelpers", "StringToAnsi");

                marshallingCodeStream.Emit(ILOpcode.call, emitter.NewToken(stringToAnsi));

                // Call the Array marshaller MarshalArgument
                return(base.MarshalArgument(context.GetWellKnownType(WellKnownType.Byte).MakeArrayType(), emitter, marshallingCodeStream, unmarshallingCodeStream));
            }
        }
Пример #8
0
 public void EmitMarshallingIL(ILEmitter emitter, ILCodeStream marshallingCodeStream, ILCodeStream callsiteSetupCodeStream, ILCodeStream unmarshallingCodeStream, ILCodeStream returnValueCodeStream)
 {
     if (!PInvokeParameterMetadata.Return)
     {
         marshallingCodeStream.EmitLdArg(PInvokeParameterMetadata.Index - 1);
         NativeType = MarshalArgument(ManagedType, emitter, marshallingCodeStream, unmarshallingCodeStream);
         IL.Stubs.ILLocalVariable vMarshalledTypeTemp = emitter.NewLocal(NativeType);
         marshallingCodeStream.EmitStLoc(vMarshalledTypeTemp);
         callsiteSetupCodeStream.EmitLdLoc(vMarshalledTypeTemp);
     }
     else
     {
         NativeType = MarshalReturn(ManagedType, emitter, marshallingCodeStream, returnValueCodeStream);
     }
 }
Пример #9
0
        protected virtual void EmitForwardArgumentMarshallingIL()
        {
            if (Return)
            {
                EmitMarshalReturnValueManagedToNative();
            }
            else
            {
                _ilCodeStreams.MarshallingCodeStream.EmitLdArg(PInvokeParameterMetadata.Index - 1);

                EmitMarshalArgumentManagedToNative();

                Debug.Assert(NativeParameterType != null);

                IL.Stubs.ILLocalVariable vMarshalledTypeTemp = _ilCodeStreams.Emitter.NewLocal(NativeParameterType);
                _ilCodeStreams.MarshallingCodeStream.EmitStLoc(vMarshalledTypeTemp);
                _ilCodeStreams.CallsiteSetupCodeStream.EmitLdLoc(vMarshalledTypeTemp);
            }
        }