protected override CodeObject GenerateCodeDom() { CodeTypeMember codeDom; IntPtr funcDescPtr; FUNCDESC funcDesc; // Have to get the FUNCDESC from the _typeInfo because // it cannot be saved. The reason for this is that a TYPEDESC // may have a pointer to another TYPEDESC which is allocated // in the unmanaged memory and that pointer won't be any good // outside of the scope where the FUNCDESC is held. _typeInfo.GetFuncDesc(_index, out funcDescPtr); funcDesc = (FUNCDESC)Marshal.PtrToStructure(funcDescPtr, typeof(FUNCDESC)); if (funcDesc.invkind == INVOKEKIND.INVOKE_FUNC) { CodeMemberMethod meth; meth = new CodeMemberMethod(); codeDom = meth; TYPEDESC retType = funcDesc.elemdescFunc.tdesc; if (_parameters.Count > 0) { int limit = _parameters.Count; // If the last parameter is a retval and the // function returns an HRESULT, then make // the function return the last parameter if ((VarEnum)funcDesc.elemdescFunc.tdesc.vt == VarEnum.VT_HRESULT) { ComParamInfo lastParam = (ComParamInfo) _parameters[_parameters.Count - 1]; if ((lastParam._paramFlags & PARAMFLAG.PARAMFLAG_FRETVAL) != 0) { IntPtr elemPtr = funcDesc.lprgelemdescParam; ELEMDESC elemDesc = new ELEMDESC(); // Point to the last one elemPtr = new IntPtr(elemPtr.ToInt64() + ((_parameters.Count - 1) * Marshal.SizeOf(elemDesc))); elemDesc = (ELEMDESC) Marshal.PtrToStructure(elemPtr, typeof(ELEMDESC)); // Make the return type the last parameter's retType = elemDesc.tdesc; limit--; } } // Only add up to the limit // (may omit the last paremeter) AddDomParams(funcDesc, meth, limit); } // HRESULT becomes void because its handled by the exception // mechanism, we just leave the return type null if ((VarEnum)retType.vt != VarEnum.VT_HRESULT) { String typeName = TypeLibUtil.TYPEDESCToString (_typeLib, _typeInfo, retType, !TypeLibUtil.COMTYPE); // Get rid of the ref since this is now a return type if (typeName.StartsWith("ref ")) typeName = typeName.Substring(4); if (TraceUtil.If(this, TraceLevel.Info)) { Trace.WriteLine(this, "CG - " + Name + " return: " + typeName); } meth.ReturnType = new CodeTypeReference(typeName); } } else { CodeMemberProperty prop; prop = new CodeMemberProperty(); codeDom = prop; prop.Type = new CodeTypeReference (TypeLibUtil.TYPEDESCToString (_typeLib, _typeInfo, funcDesc.elemdescFunc.tdesc, !TypeLibUtil.COMTYPE)); } codeDom.Name = Name; codeDom.Attributes = MemberAttributes.Public; _typeInfo.ReleaseFuncDesc(funcDescPtr); return codeDom; }