public unsafe MethodDesc(string name, string dll, string entryPoint, FUNCDESC funcdesc, string[] argumentNames, Func <uint, TypeDesc> typeFactory) { string tmpl = "___overloaded000"; if ((name.Length > tmpl.Length) && (name.IndexOf("___overloaded") == (name.Length - tmpl.Length))) { name = name.Substring(0, name.Length - tmpl.Length); } Name = EscapMethodName(name); Dll = dll; EntryPoint = entryPoint; Offset = funcdesc.oVft; ReturnValue = new ParameterDesc(funcdesc.elemdescFunc, string.Empty, typeFactory, 0, false, null); List <ParameterDesc> parameters = new List <ParameterDesc>(); for (int i = 0; i < funcdesc.cParams; i++) { parameters.Add(new ParameterDesc(funcdesc.lprgelemdescParam[i], (i < argumentNames.Length) ? argumentNames[i] : "__arg" + i, typeFactory, 0, false, null)); } Parameters = parameters.AsReadOnly(); //if (funcdesc.cParamsOpt != 0) // throw new Exception("Variable number of optional parameters is not supported"); //if (funcdesc.invkind != INVOKEKIND.INVOKE_FUNC) // throw new Exception("Only functions are currently supported"); if (funcdesc.cScodes >= 1) { throw new Exception("Only one return value is supported"); } switch (funcdesc.callconv) { case System.Runtime.InteropServices.ComTypes.CALLCONV.CC_CDECL: Convention = CallingConvention.Cdecl; break; case System.Runtime.InteropServices.ComTypes.CALLCONV.CC_STDCALL: Convention = CallingConvention.StdCall; break; default: throw new Exception("Calling convention " + funcdesc.callconv + " is not supported"); } switch (funcdesc.funckind) { case FUNCKIND.FUNC_DISPATCH: case FUNCKIND.FUNC_VIRTUAL: case FUNCKIND.FUNC_PUREVIRTUAL: case FUNCKIND.FUNC_NONVIRTUAL: case FUNCKIND.FUNC_STATIC: break; default: throw new Exception("Function kind " + funcdesc.funckind + " is not supported"); } }
public FieldDeclaration(ParameterDesc parameter, BaseTypeDeclaration container, AccessModifierType accessModifier) : base(container, 0) { if (parameter.Hidden) accessModifier = AccessModifierType.Private; string fieldType; if (parameter.ArraySizes.Any()) fieldType = new ArrayWrapperDeclararation(parameter, container, accessModifier).TypeName; else fieldType = parameter.TypeDeclaration; WriteLine(() => accessModifier + " " + fieldType + " " + parameter.Name + ";"); }
public unsafe MethodDesc(string name, string dll, string entryPoint, FUNCDESC funcdesc, string[] argumentNames, Func<uint, TypeDesc> typeFactory) { string tmpl = "___overloaded000"; if ((name.Length > tmpl.Length) && (name.IndexOf("___overloaded") == (name.Length - tmpl.Length))) name = name.Substring(0, name.Length - tmpl.Length); Name = EscapMethodName(name); Dll = dll; EntryPoint = entryPoint; Offset = funcdesc.oVft; ReturnValue = new ParameterDesc(funcdesc.elemdescFunc, string.Empty, typeFactory, 0, false, null); List<ParameterDesc> parameters = new List<ParameterDesc>(); for (int i = 0; i < funcdesc.cParams; i++) parameters.Add(new ParameterDesc(funcdesc.lprgelemdescParam[i], (i < argumentNames.Length) ? argumentNames[i] : "__arg" + i, typeFactory, 0, false, null)); Parameters = parameters.AsReadOnly(); //if (funcdesc.cParamsOpt != 0) // throw new Exception("Variable number of optional parameters is not supported"); //if (funcdesc.invkind != INVOKEKIND.INVOKE_FUNC) // throw new Exception("Only functions are currently supported"); if (funcdesc.cScodes >= 1) throw new Exception("Only one return value is supported"); switch (funcdesc.callconv) { case System.Runtime.InteropServices.ComTypes.CALLCONV.CC_CDECL: Convention = CallingConvention.Cdecl; break; case System.Runtime.InteropServices.ComTypes.CALLCONV.CC_STDCALL: Convention = CallingConvention.StdCall; break; default: throw new Exception("Calling convention " + funcdesc.callconv + " is not supported"); } switch (funcdesc.funckind) { case FUNCKIND.FUNC_DISPATCH: case FUNCKIND.FUNC_VIRTUAL: case FUNCKIND.FUNC_PUREVIRTUAL: case FUNCKIND.FUNC_NONVIRTUAL: case FUNCKIND.FUNC_STATIC: break; default: throw new Exception("Function kind " + funcdesc.funckind + " is not supported"); } }
public static string GetValueInitializer(ParameterDesc parameter) { string result; if (parameter.Value == null || parameter.Value.ToString() == "0") result = "null"; else result = parameter.Value.ToString(); if (result == "null") { if (((parameter.Type.Kind == TypeKind.Interface) && (parameter.IndirectionLevel == 1)) || (parameter.IndirectionLevel == 0)) result = "default(" + parameter.TypeDeclaration + ")"; } else result = "(" + parameter.TypeDeclaration + ")" + result; return result; }
private static string GetParameterTypeDeclaration(ParameterDesc parameter) { return parameter.TypeDeclaration + (parameter.ArraySizes.Any() ? "*" : ""); }
public ConstDeclaration(ParameterDesc parameter, BaseTypeDeclaration container, AccessModifierType accessModifier) : base(container, 0) { WriteLine(() => accessModifier + " const " + ((parameter.Value is string) ? "string" : parameter.TypeDeclaration) + " " + parameter.Name + " = " + GetValueInitializer(parameter.Value) + ";"); }
public ArrayWrapperDeclararation(ParameterDesc parameter, BaseTypeDeclaration container, AccessModifierType accessModifier) : base(parameter.Type, container, accessModifier) { this.arraySizes = parameter.ArraySizes; int totalLength = 1; int[] sizes = arraySizes.ToArray(); List<string> lengthConstants = new List<string>(); List<string> indexerParameters = new List<string>(); for(int i = 0; i < sizes.Length; i++) { totalLength *= sizes[i]; lengthConstants.Add("length" + i.ToString()); indexerParameters.Add("index" + i.ToString()); } List<string> parts = new List<string>(); for (int i = 0; i < sizes.Length; i++) { List<string> multipliers = new List<string>(); multipliers.Add(indexerParameters[i]); for (int j = i; j < (sizes.Length - 1); j++) multipliers.Add(lengthConstants[j]); parts.Add(string.Join(" * ", multipliers)); } string index = string.Join(" + ", parts); bool canBeFixedArray = IsPrimitiveType(parameter.Type.Name) && (parameter.IndirectionLevel == 0); WriteBaseLine(() => "{"); for (int i = 0; i < sizes.Length; i++) AddTextBlock(new ConstDeclaration(new TypeDesc("int"), lengthConstants[i], this, AccessModifierType.Private, sizes[i])); WriteLine(); if (!canBeFixedArray) { for (int i = 0; i < totalLength; i++) AddTextBlock(new FieldDeclaration(parameter.Type, "data" + i.ToString(), this, AccessModifierType.Private)); } else AddTextBlock(new FieldDeclaration(parameter.Type, "data", this, AccessModifierType.Private, totalLength)); WriteLine(); WriteLine(() => AccessModifier + " unsafe " + parameter.Type.Name + " this[" + string.Join(", ", indexerParameters.Select(x => "int " + x)) + "]"); WriteLine(() => "{"); WriteLine(() => " get"); WriteLine(() => " {"); WriteLine(() => " fixed (" + parameter.Type.Name + "* pointer = " + (canBeFixedArray ? "data" : "&data0") + ")"); WriteLine(() => " {"); WriteLine(() => " return pointer[" + index + "];"); WriteLine(() => " }"); WriteLine(() => " }"); WriteLine(() => " set"); WriteLine(() => " {"); WriteLine(() => " fixed (" + parameter.Type.Name + "* pointer = " + (canBeFixedArray ? "data" : "&data0") + ")"); WriteLine(() => " {"); WriteLine(() => " pointer[" + index + "] = value;"); WriteLine(() => " }"); WriteLine(() => " }"); WriteLine(() => "}"); WriteLine(); WriteLine(() => "public static unsafe implicit operator " + parameter.Type.Name + "[](" + TypeName + " value)"); WriteLine(() => "{"); WriteLine(() => " " + parameter.Type.Name + "[] result = new " + parameter.Type.Name + "[" + totalLength + "];"); WriteLine(() => " " + parameter.Type.Name + "* pointer = " + (canBeFixedArray ? "value.data" : "&value.data0") + ";"); WriteLine(() => " {"); WriteLine(() => " for (int i = 0; i < " + totalLength + "; i++)"); WriteLine(() => " result[i] = pointer[i];"); WriteLine(() => " }"); WriteLine(() => " return result;"); WriteLine(() => "}"); WriteLine(); WriteLine(() => "public static unsafe implicit operator " + TypeName + "(" + parameter.Type.Name + "[] value)"); WriteLine(() => "{"); WriteLine(() => " if (value == null)"); WriteLine(() => " throw new ArgumentNullException(\"value\");"); WriteLine(() => " " + TypeName + " result = new " + TypeName + "();"); WriteLine(() => " " + parameter.Type.Name + "* pointer = " + (canBeFixedArray ? "result.data" : "&result.data0") + ";"); WriteLine(() => " for (int i = 0; i < ((value.Length < " + totalLength + ") ? value.Length : " + totalLength + "); i++)"); WriteLine(() => " pointer[i] = value[i];"); WriteLine(() => " return result;"); WriteLine(() => "}"); WriteBaseLine(() => "}"); }