internal override Expression MarshalToRef(Expression parameter) { parameter = Marshal(parameter); // parameter == null ? IntPtr.Zero : Marshal.GetIDispatchForObject(parameter); return(Expression.Condition( Expression.Equal(parameter, Expression.Constant(null)), Expression.Constant(IntPtr.Zero), Expression.Call( ComRuntimeHelpers.GetGetIDispatchForObjectMethod(), parameter ) )); }
/// <summary> /// Create a stub for the target of the optimized lopop. /// </summary> /// <returns></returns> private Expression MakeIDispatchInvokeTarget() { Debug.Assert(_varEnumSelector.VariantBuilders.Length == _totalExplicitArgs); List <Expression> exprs = new List <Expression>(); // // _dispId = ((DispCallable)this).ComMethodDesc.DispId; // exprs.Add( Expression.Assign( DispIdVariable, Expression.Property(_method, typeof(ComMethodDesc).GetProperty(nameof(ComMethodDesc.DispId))) ) ); // // _dispParams.rgvararg = RuntimeHelpers.UnsafeMethods.ConvertVariantByrefToPtr(ref _paramVariants._element0) // if (_totalExplicitArgs != 0) { exprs.Add( Expression.Assign( Expression.Field( DispParamsVariable, typeof(ComTypes.DISPPARAMS).GetField(nameof(ComTypes.DISPPARAMS.rgvarg)) ), Expression.Call( typeof(UnsafeMethods).GetMethod(nameof(UnsafeMethods.ConvertVariantByrefToPtr)), VariantArray.GetStructField(ParamVariantsVariable, 0) ) ) ); } // // _dispParams.cArgs = <number_of_params>; // exprs.Add( Expression.Assign( Expression.Field( DispParamsVariable, typeof(ComTypes.DISPPARAMS).GetField(nameof(ComTypes.DISPPARAMS.cArgs)) ), Expression.Constant(_totalExplicitArgs) ) ); if (_methodDesc.IsPropertyPut) { // // dispParams.cNamedArgs = 1; // dispParams.rgdispidNamedArgs = RuntimeHelpers.UnsafeMethods.GetNamedArgsForPropertyPut() // exprs.Add( Expression.Assign( Expression.Field( DispParamsVariable, typeof(ComTypes.DISPPARAMS).GetField(nameof(ComTypes.DISPPARAMS.cNamedArgs)) ), Expression.Constant(1) ) ); exprs.Add( Expression.Assign( PropertyPutDispIdVariable, Expression.Constant(ComDispIds.DISPID_PROPERTYPUT) ) ); exprs.Add( Expression.Assign( Expression.Field( DispParamsVariable, typeof(ComTypes.DISPPARAMS).GetField(nameof(ComTypes.DISPPARAMS.rgdispidNamedArgs)) ), Expression.Call( typeof(UnsafeMethods).GetMethod(nameof(UnsafeMethods.ConvertInt32ByrefToPtr)), PropertyPutDispIdVariable ) ) ); } else { // // _dispParams.cNamedArgs = N; // exprs.Add( Expression.Assign( Expression.Field( DispParamsVariable, typeof(ComTypes.DISPPARAMS).GetField(nameof(ComTypes.DISPPARAMS.cNamedArgs)) ), Expression.Constant(_keywordArgNames.Length) ) ); } // // _dispatchObject = _dispatch // _dispatchPointer = Marshal.GetIDispatchForObject(_dispatchObject); // exprs.Add(Expression.Assign(DispatchObjectVariable, _dispatch)); exprs.Add( Expression.Assign( DispatchPointerVariable, Expression.Call( ComRuntimeHelpers.GetGetIDispatchForObjectMethod(), DispatchObjectVariable ) ) ); Expression tryStatements = GenerateTryBlock(); Expression finallyStatements = GenerateFinallyBlock(); exprs.Add(Expression.TryFinally(tryStatements, finallyStatements)); exprs.Add(ReturnValueVariable); var vars = new List <ParameterExpression>(); foreach (var variant in _varEnumSelector.VariantBuilders) { if (variant.TempVariable != null) { vars.Add(variant.TempVariable); } } return(Expression.Block(vars, exprs)); }