internal static Type GetTypeForVarEnum(VarEnum vt) { Type type; switch (vt) { // VarEnums which can be used in VARIANTs, but which cannot occur in a TYPEDESC case VarEnum.VT_EMPTY: case VarEnum.VT_NULL: case VarEnum.VT_RECORD: type = typeof(void); break; // VarEnums which are not used in VARIANTs, but which can occur in a TYPEDESC case VarEnum.VT_VOID: type = typeof(void); break; case VarEnum.VT_HRESULT: type = typeof(int); break; case ((VarEnum)37): // VT_INT_PTR: type = typeof(IntPtr); break; case ((VarEnum)38): // VT_UINT_PTR: type = typeof(UIntPtr); break; case VarEnum.VT_SAFEARRAY: case VarEnum.VT_CARRAY: type = typeof(Array); break; case VarEnum.VT_LPSTR: case VarEnum.VT_LPWSTR: type = typeof(string); break; case VarEnum.VT_PTR: case VarEnum.VT_USERDEFINED: type = typeof(object); break; // For VarEnums that can be used in VARIANTs and well as TYPEDESCs, just use VarEnumSelector default: type = VarEnumSelector.GetManagedMarshalType(vt); break; } return(type); }
/// <summary> /// Creates a representation for the parameter of a COM method /// </summary> internal ComParamDesc(ref ELEMDESC elemDesc, string name) { // Ensure _defaultValue is set to DBNull.Value regardless of whether or not the // default value is extracted from the parameter description. Failure to do so // yields a runtime exception in the ToString() function. DefaultValue = DBNull.Value; if (!string.IsNullOrEmpty(name)) { // This is a parameter, not a return value IsOut = (elemDesc.desc.paramdesc.wParamFlags & PARAMFLAG.PARAMFLAG_FOUT) != 0; IsOptional = (elemDesc.desc.paramdesc.wParamFlags & PARAMFLAG.PARAMFLAG_FOPT) != 0; // TODO: The PARAMDESCEX struct has a memory issue that needs to be resolved. For now, we ignore it. //_defaultValue = PARAMDESCEX.GetDefaultValue(ref elemDesc.desc.paramdesc); } _name = name; _vt = (VarEnum)elemDesc.tdesc.vt; TYPEDESC typeDesc = elemDesc.tdesc; while (true) { if (_vt == VarEnum.VT_PTR) { ByReference = true; } else if (_vt == VarEnum.VT_ARRAY) { IsArray = true; } else { break; } TYPEDESC childTypeDesc = (TYPEDESC)Marshal.PtrToStructure(typeDesc.lpValue, typeof(TYPEDESC)); _vt = (VarEnum)childTypeDesc.vt; typeDesc = childTypeDesc; } VarEnum vtWithoutByref = _vt; if ((_vt & VarEnum.VT_BYREF) != 0) { vtWithoutByref = (_vt & ~VarEnum.VT_BYREF); ByReference = true; } ParameterType = VarEnumSelector.GetTypeForVarEnum(vtWithoutByref); }
internal DynamicMetaObject Invoke() { _keywordArgNames = _callInfo.ArgumentNames.ToArray(); _totalExplicitArgs = _args.Length; Type[] marshalArgTypes = new Type[_args.Length]; // We already tested the instance, so no need to test it again for (int i = 0; i < _args.Length; i++) { DynamicMetaObject curMo = _args[i]; marshalArgTypes[i] = MarshalType(curMo, _isByRef[i]); } _varEnumSelector = new VarEnumSelector(marshalArgTypes); return(new DynamicMetaObject( CreateScope(MakeIDispatchInvokeTarget()), BindingRestrictions.Combine(_args).Merge(_restrictions) )); }