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