public void Write(TextWriter output, IList <NamedConstruct> members, CApiGeneratorOptions opts) { output.WriteLine("/*****************************************************************"); output.WriteLine(" This file is automatically generated by nclang CApiGenerator.exe."); output.WriteLine(" *****************************************************************/"); foreach (var source in opts.Sources) { output.WriteLine("#include \"" + source + "\""); } output.WriteLine("extern \"C\" {"); // forward decls. foreach (var o in members.OfType <ClassDeclaration> ()) { if (!opts.ShouldGenerateCodeFor(o)) { continue; // skip unmatched file } output.WriteLine($"class {o.CTypeName ()} : {o.Namespace}{o.nssep}{o.Name}; // {o.SourceFileName} ({o.Line}, {o.Column})"); output.WriteLine(); } foreach (var o in members.OfType <ClassDeclaration> ()) { if (!opts.ShouldGenerateCodeFor(o)) { continue; // skip unmatched file } output.WriteLine($"// {o.Name} Constructors and destructor."); if (!o.Constructors.Any()) { output.WriteLine($"{o.CTypeName ()}* {o.CName ()}_new () {{ return new {o.CTypeName ()} (); }}"); } foreach (var c in o.Constructors) { var pdefs = string.Join(", ", c.Parameters.Select(p => p.Type + " " + p.Name)); var pcalls = string.Join(", ", c.Parameters.Select(p => p.Name)); output.WriteLine($"void* {o.CName ()}_new ({pdefs}) {{ return new {o.CTypeName ()} ({pcalls}); }}"); } output.WriteLine($"void {o.CName ()}_delete ({o.CTypeName ()} *instance) {{ delete instance; }}"); output.WriteLine(); var targetFields = o.Fields.Where(f => f.Access != CXXAccessSpecifier.Private); if (targetFields.Any()) { output.WriteLine($"// {o.Name} Field accessors"); } foreach (var f in targetFields) { if (f.IsStatic || f.IsConst) { // static/const output.WriteLine($"{f.CTypeName ()} {o.CName ()}_get_{f.CName ()} () {{ return {o.Name}::{f.Name}; }}"); if (!f.IsConst) { output.WriteLine($"void {o.CName ()}_set_{f.CName ()} ({f.CTypeName ()} value) {{ {o.Name}::{f.Name} = value; }}"); } } else { // instance output.WriteLine($"{f.CTypeName ()} {o.CName ()}_get_{f.CName ()} ({o.CName ()} *instance) {{ return (({o.Name}*)instance)->{f.Name}; }}"); output.WriteLine($"void {o.CName ()}_set_{f.CName ()} ({o.CName ()} *instance, {f.Type} value) {{ (({o.Name}*)instance)->{f.Name} = value; }}"); } output.WriteLine(); } var targetFunctions = o.Functions.Where(f => f.Access != CXXAccessSpecifier.Private); if (targetFunctions.Any()) { output.WriteLine($"// {o.Name} Function delegates"); } foreach (var f in targetFunctions) { // static/const string optComma = f.Parameters.Any() ? ", " : ""; output.Write($"{f.CTypeReturn ()} {o.CName ()}_{f.CName ()} ({o.CTypeName ()} *instance{optComma} {string.Join (", ", f.Parameters.Select (a => a.ToTypeAndName ()))}) "); string retspec = f.Return == "void" ? string.Empty : "return "; output.WriteLine($"{{ {retspec}(({o.Name}*)instance)->{f.Name} ({string.Join (", ", f.Parameters.Select (a => a.Name))}); }}"); } output.WriteLine(); } foreach (var o in members.OfType <Variable> ()) { if (!opts.ShouldGenerateCodeFor(o)) { continue; // skip unmatched file } output.WriteLine(); } foreach (var o in members.OfType <Function> ().Where(m => m.Kind != CursorKind.Constructor)) { if (!opts.ShouldGenerateCodeFor(o)) { continue; // skip unmatched file } o.Write(output); output.WriteLine(); } output.WriteLine("} // extern \"C\""); output.Close(); }