public PInvokeMethodData(MethodDesc method, PInvokeILEmitterConfiguration config, MarshalDirection direction) { TargetMethod = method; PInvokeILEmitterConfiguration = config; Context = method.Context; ImportMetadata = method.GetPInvokeMethodMetadata(); Direction = direction; }
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); } }
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); }
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); }
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); }
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); }
/// <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; }