void ComWrappersImpl.IDispatch.Invoke( int dispIdMember, ref Guid riid, int lcid, INVOKEKIND wFlags, ref DISPPARAMS pDispParams, IntPtr VarResult, IntPtr pExcepInfo, IntPtr puArgErr) { MemberInfo?memberInfo; if (!this.dispIdToMemberInfo.TryGetValue(dispIdMember, out memberInfo)) { throw new COMException(null, DISP_E_UNKNOWNNAME); } BindingFlags invokeFlags = BindingFlags.Public | BindingFlags.Instance; if (wFlags.HasFlag(INVOKEKIND.INVOKE_FUNC) && memberInfo.MemberType == MemberTypes.Method) { invokeFlags |= BindingFlags.InvokeMethod; } else { throw new NotImplementedException("Operation not implemented."); } // Use reflection to dispatch to the indicated function. // Note that this is exactly what the internal implementation of IDispatch does so there // isn't a lot of difference in cost. var result = this.objType.InvokeMember( memberInfo.Name, invokeFlags, null, this.obj, MarshalArguments(ref pDispParams)); if (result != null) { // Lots of special cases should be addressed here. // * Arrays, IEnumerable // * IDispatch/IUnknown instances // * .NET object could be wrapped by ComWrappers // * .NET objects that are already COM objects can be safely passed on // * etc Marshal.GetNativeVariantForObject(result, VarResult); } }
public DispatchMember(string name, int dispid, INVOKEKIND invokeKind) : this(name, dispid) { if (invokeKind.HasFlag(INVOKEKIND.INVOKE_FUNC)) { DispatchFlags |= DispatchFlags.Method; } if (invokeKind.HasFlag(INVOKEKIND.INVOKE_PROPERTYGET)) { DispatchFlags |= DispatchFlags.PropertyGet; } if (invokeKind.HasFlag(INVOKEKIND.INVOKE_PROPERTYPUT)) { DispatchFlags |= DispatchFlags.PropertyPut; } if (invokeKind.HasFlag(INVOKEKIND.INVOKE_PROPERTYPUTREF)) { DispatchFlags |= DispatchFlags.PropertyPutRef; } }