private static void OutputDeallocation(StreamWriter writer, RealParameterTuple parameter, int index) { if (!parameter.Item3 && !parameter.Item4) { return; } writer.Write("Marshal.FreeHGlobal(__local{0});", index + 1); writer.WriteLine(); }
private static void OutputAllocation(StreamWriter writer, RealParameterTuple parameter, int index) { if (!parameter.Item3 && !parameter.Item4) { return; } // Get the type int position = index + 1; String type = parameter.Item2; bool isRef = type.StartsWith("ref "); bool isOut = type.StartsWith("out "); bool isArray = type.EndsWith("[]"); if (isRef) { type = type.Replace("ref ", String.Empty); } if (isOut) { type = type.Replace("out ", String.Empty); } if (isArray) { type = type.Replace("[]", String.Empty); } if (isRef || isOut) { writer.Write("IntPtr __local{0} = Marshal.AllocHGlobal(Marshal.SizeOf(typeof({1})));", position, type); writer.WriteLine(); } if (isArray) { writer.Write("IntPtr __local{0} = Marshal.AllocHGlobal(Marshal.SizeOf(typeof({1})) * {2}.Length);", position, type, parameter.Item1); writer.WriteLine(); } }
private static void OutputUnmarshalling(StreamWriter writer, RealParameterTuple parameter, int index) { if (!parameter.Item4) { return; } // Get the type int position = index + 1; String type = parameter.Item2; bool isOut = type.StartsWith("out "); bool isArray = type.EndsWith("[]"); if (isOut) { type = type.Replace("out ", String.Empty); } if (isArray) { type = type.Replace("[]", String.Empty); } if (isOut) { switch (type) { case "GLubyte": writer.Write("{1} = Marshal.ReadByte(__local{0});", position, parameter.Item1); break; case "GLboolean": case "GLchar": case "GLbyte": case "GLcharARB": writer.Write("{1} = ({2}) Marshal.ReadByte(__local{0});", position, parameter.Item1, type); break; case "GLshort": writer.Write("{1} = Marshal.ReadInt16(__local{0});", position, parameter.Item1); break; case "GLushort": case "GLhalfARB": case "GLhalf": writer.Write("{1} = ({2}) Marshal.ReadInt16(__local{0});", position, parameter.Item1, type); break; case "GLsizei": case "GLint": writer.Write("{1} = ({2}) Marshal.ReadInt32(__local{0});", position, parameter.Item1, type); break; case "GLuint": case "GLenum": writer.Write("{1} = ({2}) Marshal.ReadInt32(__local{0});", position, parameter.Item1, type); break; case "GLintptr": case "GLsizeiptr": case "GLhandleARB": case "GLintptrARB": case "GLsizeiptrARB": writer.Write("{1} = ({2}) Marshal.ReadIntPtr(__local{0});", position, parameter.Item1, type); break; case "GLfloat": case "GLclampf": case "GLdouble": case "GLclampd": writer.Write("{1} = ({2}) Marshal.PtrToStructure(__local{0}, typeof({2}));", position, parameter.Item1, type); break; default: writer.Write("Not Supported: {0}", parameter.Type); break; } writer.WriteLine(); } if (isArray) { // TODO } }
private static void OutputMarshalling(StreamWriter writer, RealParameterTuple parameter, int index) { if (!parameter.Item3) { return; } // Get the type int position = index + 1; String type = parameter.Item2; bool isRef = type.StartsWith("ref "); bool isArray = type.EndsWith("[]"); if (isRef) { type = type.Replace("ref ", String.Empty); } if (isArray) { type = type.Replace("[]", String.Empty); } if (isRef) { switch (type) { case "GLboolean": case "GLubyte": writer.Write("Marshal.WriteByte(__local{0}, {1});", position, parameter.Item1); break; case "GLchar": case "GLbyte": case "GLcharARB": writer.Write("Marshal.WriteByte(__local{0}, (GLubyte) {1});", position, parameter.Item1); break; case "GLshort": writer.Write("Marshal.WriteInt16(__local{0}, {1});", position, parameter.Item1); break; case "GLushort": case "GLhalfARB": case "GLhalf": writer.Write("Marshal.WriteInt16(__local{0}, (GLshort) {1});", position, parameter.Item1); break; case "GLsizei": case "GLint": writer.Write("Marshal.WriteInt32(__local{0}, {1});", position, parameter.Item1); break; case "GLuint": case "GLenum": writer.Write("Marshal.WriteInt32(__local{0}, (GLint) {1});", position, parameter.Item1); break; case "GLintptr": case "GLsizeiptr": case "GLhandleARB": case "GLintptrARB": case "GLsizeiptrARB": writer.Write("Marshal.WriteIntPtr(__local{0}, {1});", position, parameter.Item1); break; case "GLfloat": case "GLclampf": case "GLdouble": case "GLclampd": writer.Write("Marshal.StructureToPtr({1}, __local{0}, false);", position, parameter.Item1); break; default: writer.Write("Not Supported: {0}", parameter.Type); break; } writer.WriteLine(); } if (isArray) { switch (type) { case "GLchar": case "GLbyte": case "GLcharARB": writer.Write("GLubyte[] __array{0} = Array.ConvertAll({1}, item => (GLubyte) item);", position, parameter.Item1); writer.WriteLine(); writer.Write("Marshal.Copy(__array{0}, 0, __local{0}, __array{0}.Length);", position); break; case "GLushort": case "GLhalfARB": case "GLhalf": writer.Write("GLshort[] __array{0} = Array.ConvertAll({1}, item => (GLshort) item);", position, parameter.Item1); writer.WriteLine(); writer.Write("Marshal.Copy(__array{0}, 0, __local{0}, __array{0}.Length);", position); break; case "GLenum": case "GLuint": writer.Write("GLint[] __array{0} = Array.ConvertAll({1}, item => (GLint) item);", position, parameter.Item1); writer.WriteLine(); writer.Write("Marshal.Copy(__array{0}, 0, __local{0}, __array{0}.Length);", position); break; default: writer.Write("Marshal.Copy({1}, 0, __local{0}, {1}.Length);", position, parameter.Item1); break; } writer.WriteLine(); } }
private static void OutputMethod(StreamWriter writer, String line, String method, String returnType, IEnumerable <RealParameterTuple> parameters) { bool hasReturn = (returnType != "void"); bool hasBody = parameters.Any(p => p.NeedMarshalling || p.NeedUnmarshalling); // Create the parameter list String parameterString = String.Join(", ", parameters.Select(p => String.Format("{0} {1}", p.Type, p.Name)).ToArray()); // Output documentation writer.WriteLine("/// <summary>"); writer.WriteLine(String.Format("/// <para>Original signature is '{0}'</para>", line.Trim())); writer.WriteLine("/// </summary>"); // Output the method if (!hasBody) { writer.WriteLine(String.Format("[DllImport(OPENGL, EntryPoint = \"{0}\")]", method)); } writer.Write(String.Format("public static {0} {1} {2}({3})", hasBody ? String.Empty : "extern", returnType, method, parameterString)); if (!hasBody) { writer.WriteLine(";"); } else { writer.WriteLine(); writer.WriteLine("{"); // Marshal the parameters for (int i = 0; i < parameters.Count(); i++) { OutputAllocation(writer, parameters.ElementAt(i), i); OutputMarshalling(writer, parameters.ElementAt(i), i); } // Output the call if (hasReturn) { writer.Write("{0} result = ", returnType); } writer.Write("{0}(", method); for (int i = 0; i < parameters.Count(); i++) { if (i > 0) { writer.Write(", "); } RealParameterTuple parameter = parameters.ElementAt(i); if (parameter.NeedMarshalling || parameter.NeedUnmarshalling) { writer.Write("__local{0}", i + 1); } else { writer.Write(parameter.Name); } } writer.WriteLine(");"); // Unmarshal the parameters for (int i = 0; i < parameters.Count(); i++) { OutputUnmarshalling(writer, parameters.ElementAt(i), i); OutputDeallocation(writer, parameters.ElementAt(i), i); } if (hasReturn) { writer.Write("return result;"); } writer.WriteLine("}"); } writer.WriteLine(); }