protected void AddParams(FUNCDESC funcDesc, String[] names, int paramCount) { IntPtr elemPtr = funcDesc.lprgelemdescParam; for (int i = 0; i < paramCount; i++) { ELEMDESC elemDesc = (ELEMDESC)Marshal.PtrToStructure(elemPtr, typeof(ELEMDESC)); ComParamInfo pi = new ComParamInfo (names[i + 1], TypeLibUtil.TYPEDESCToString (_typeLib, _typeInfo, elemDesc.tdesc, TypeLibUtil.COMTYPE), elemDesc.desc.paramdesc.wParamFlags); _parameters.Add(pi); // Point to the next one elemPtr = new IntPtr(elemPtr.ToInt64() + Marshal.SizeOf(elemDesc)); } }
protected void AddDomParams(FUNCDESC funcDesc, CodeMemberMethod meth, int limit) { IntPtr elemPtr = funcDesc.lprgelemdescParam; for (int i = 0; i < limit; i++) { ELEMDESC elemDesc = (ELEMDESC)Marshal.PtrToStructure(elemPtr, typeof(ELEMDESC)); ComParamInfo parameter = (ComParamInfo) _parameters[i]; String paramType = TypeLibUtil.TYPEDESCToString (_typeLib, _typeInfo, elemDesc.tdesc, !TypeLibUtil.COMTYPE); String paramInOut = null; if ((parameter._paramFlags & PARAMFLAG.PARAMFLAG_FIN) != 0) { paramInOut = "In"; } else if ((parameter._paramFlags & PARAMFLAG.PARAMFLAG_FOUT) != 0) { paramInOut = "Out"; // Ref becomes out for an output parameter if (paramType.StartsWith("ref ")) { paramType = "out " + paramType.Substring(4); } else { paramType = "out " + paramType; } } CodeParameterDeclarationExpression paramExpr = new CodeParameterDeclarationExpression (paramType, parameter._name); if (paramInOut != null) { paramExpr.CustomAttributes.Add (new CodeAttributeDeclaration ("System.Runtime.InteropServices." + paramInOut)); } meth.Parameters.Add(paramExpr); // Point to the next one elemPtr = new IntPtr(elemPtr.ToInt64() + Marshal.SizeOf(elemDesc)); } }
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); }