public void ParseAssert(string text, Action <CppCompilation> assertCompilation, CppParserOptions options = null, bool asFile = true) { if (assertCompilation == null) { throw new ArgumentNullException(nameof(assertCompilation)); } options = options ?? new CppParserOptions(); var currentDirectory = Environment.CurrentDirectory; var headerFilename = $"{TestContext.CurrentContext.Test.FullName}-{TestContext.CurrentContext.Test.ID}.h"; var headerFile = Path.Combine(currentDirectory, headerFilename); // Parse in memory var compilation = CppParser.Parse(text, options, headerFilename); foreach (var diagnosticsMessage in compilation.Diagnostics.Messages) { Console.WriteLine(diagnosticsMessage); } assertCompilation(compilation); if (asFile) { // Parse single file from disk File.WriteAllText(headerFile, text); compilation = CppParser.ParseFile(headerFile, options); assertCompilation(compilation); } }
static void Main(string[] args) { var flavors = new string[] { "Dawn", "Browser" }; foreach (var flavor in flavors) { var headerFile = Path.Combine(AppContext.BaseDirectory, "Headers", flavor, "webgpu.h"); var options = new CppParserOptions { ParseMacros = true, Defines = { "WGPU_SHARED_LIBRARY", "_WIN32", "WGPU_SKIP_PROCS" } }; var compilation = CppParser.ParseFile(headerFile, options); // Print diagnostic messages if (compilation.HasErrors) { foreach (var message in compilation.Diagnostics.Messages) { Debug.WriteLine(message); } } else { string basePath = "..\\..\\..\\..\\WaveEngine.Bindings.WebGPU"; CsCodeGenerator.Instance.Generate(compilation, basePath, flavor); } } }
static void Main(string[] args) { var headerFile = Path.Combine(AppContext.BaseDirectory, "Headers", "renderdoc_app.h"); var options = new CppParserOptions { ParseMacros = true, Defines = { "_WIN32", } }; var compilation = CppParser.ParseFile(headerFile, options); // Print diagnostic messages if (compilation.HasErrors) { foreach (var message in compilation.Diagnostics.Messages) { Debug.WriteLine(message); } } else { string outputPath = "..\\..\\..\\..\\WaveEngine.Bindings.RenderDoc\\Generated"; CsCodeGenerator.Instance.Generate(compilation, outputPath); } }
private static CppCompilation Parse(string vlcDir) { var parserOptions = new CppParserOptions { ParseComments = NoComment }; parserOptions.IncludeFolders.Add(Path.Combine(vlcDir, include)); return(CppParser.ParseFile(BuildPath(vlcDir, vlch), parserOptions)); }
static CppCompilation Do(String file, ClConfig cfg) { var options = new CppParserOptions() { // Pass the defines -DMYDEFINE to the C++ parser Defines = { }, IncludeFolders = { }, TargetCpu = CppTargetCpu.X86_64, }; options.ParseSystemIncludes = false; options.ParseComments = false; options.AdditionalArguments.Add("-fno-complete-member-pointers"); options.AdditionalArguments.Add("/TC"); options.AdditionalArguments.Add("-std c99"); options.AdditionalArguments.Add("/c"); options.AdditionalArguments.Add("-fms-extensions"); options.AdditionalArguments.Add("-fms-compatibility"); options.AdditionalArguments.Add(" -fms-compatibility-version=19"); options.ParseAsCpp = false; options.EnableFunctionBodies(); foreach (KeyValuePair <string, string> kv in cfg.define) { String d = kv.Value == null ? (kv.Key) : (kv.Key + "=" + kv.Value); options.Defines.Add(d); } options.Defines.Add("CPP_AST_FIXED"); foreach (String include in cfg.include) { options.IncludeFolders.Add(include); } options.ConfigureForWindowsMsvc(); var compilation = CppParser.ParseFile(file, options); return(compilation); }
static void Main(string[] args) { var headerFile = Path.Combine(AppContext.BaseDirectory, "ImGUI", "cimgui.h"); var options = new CppParserOptions { ParseMacros = true, Defines = { "CIMGUI_DEFINE_ENUMS_AND_STRUCTS" } }; var compilation = CppParser.ParseFile(headerFile, options); if (compilation.HasErrors) { foreach (var message in compilation.Diagnostics.Messages) { Console.WriteLine(message); } } CsCodeGenerator.Generate(compilation, "../../../../src/SharpImGUI/Generated/"); }
public static void Main(string[] args) { // In this sample we are going to bind a few C++ classes from https://github.com/lemire/simdjson // the library has "singleheader" file so we don't have to collect all needed files + includes // see https://github.com/lemire/simdjson/tree/master/singleheader string outputFolder = "../../../Output/"; if (!Directory.Exists(outputFolder)) { Directory.CreateDirectory(outputFolder); } Console.WriteLine("Downloading simdjson sources..."); HttpClient httpClient = new HttpClient(); string simdJsonSingleHeader = httpClient.GetStringAsync("https://raw.githubusercontent.com/lemire/simdjson/master/singleheader/simdjson.h").Result; File.WriteAllText(Path.Combine(outputFolder, @"simdjson.h"), simdJsonSingleHeader); Console.WriteLine("Downloaded! Parsing..."); var options = new CppParserOptions(); // TODO: test on macOS options.ConfigureForWindowsMsvc(CppTargetCpu.X86_64); options.AdditionalArguments.Add("-std=c++17"); CppCompilation compilation = CppParser.ParseFile(Path.Combine(outputFolder, @"simdjson.h"), options); if (compilation.DumpErrorsIfAny()) { Console.ReadKey(); return; } var mapper = new TypeMapper(compilation); // Register native types we don't want to bind (or any method with them in parameters) mapper.RegisterUnsupportedTypes( "simdjson", // it's empty - we don't need it "basic_string", // TODO: "basic_string_view", // TODO "basic_ostream"); // TODO: var templateManager = new TemplateManager(); // Add additional stuff we want to see in the bindings.c templateManager .AddToCHeader(@"#include ""simdjson.h""") .SetGlobalFunctionsClassName("GlobalFunctions"); PinvokeGenerator.Generate(mapper, templateManager, @namespace: "MyNamespace", dllImportPath: @"""simdjson.dll""", outCFile: Path.Combine(outputFolder, "Bindings.c"), outCsFile: Path.Combine(outputFolder, "Bindings.cs")); Console.WriteLine("Done. See Output folder."); }
public static int Main(string[] args) { string outputPath = AppContext.BaseDirectory; if (args.Length > 0) { outputPath = args[0]; } if (!Path.IsPathRooted(outputPath)) { outputPath = Path.Combine(AppContext.BaseDirectory, outputPath); } if (!Directory.Exists(outputPath)) { Directory.CreateDirectory(outputPath); } string?headerFile = Path.Combine(AppContext.BaseDirectory, "vulkan", "vulkan.h"); var options = new CppParserOptions { ParseMacros = true, Defines = { "VK_USE_PLATFORM_ANDROID_KHR", "VK_USE_PLATFORM_IOS_MVK", "VK_USE_PLATFORM_MACOS_MVK", "VK_USE_PLATFORM_METAL_EXT", "VK_USE_PLATFORM_VI_NN", //"VK_USE_PLATFORM_WAYLAND_KHR", //"VK_USE_PLATFORM_WIN32_KHR", //"VK_USE_PLATFORM_SCREEN_QNX", "VK_ENABLE_BETA_EXTENSIONS" } }; var compilation = CppParser.ParseFile(headerFile, options); // Print diagnostic messages if (compilation.HasErrors) { foreach (var message in compilation.Diagnostics.Messages) { if (message.Type == CppLogMessageType.Error) { var currentColor = Console.ForegroundColor; Console.ForegroundColor = ConsoleColor.Red; Console.WriteLine(message); Console.ForegroundColor = currentColor; } } return(0); } bool generateFuncFile = false; if (generateFuncFile) { File.Delete("Vk.txt"); foreach (var func in compilation.Functions) { var signature = new System.Text.StringBuilder(); var argSignature = CsCodeGenerator.GetParameterSignature(func, true); signature .Append(func.ReturnType.GetDisplayName()) .Append(" ") .Append(func.Name) .Append("(") .Append(argSignature) .Append(")"); File.AppendAllText("Vk.txt", signature.ToString() + Environment.NewLine); } } CsCodeGenerator.Generate(compilation, outputPath); return(0); }
public static void Main(string[] args) { // input (single header) string headerPath = Path.Combine(Environment.CurrentDirectory, "../../src/BindingsForNativeLib/SimdJsonNative/simdjson.h"); // output string cgluePath = Path.Combine(Environment.CurrentDirectory, "../../src/BindingsForNativeLib/SimdJsonNative/bindings.cpp"); string bindingsPath = Path.Combine(Environment.CurrentDirectory, "../../src/BindingsForNativeLib/SimdJsonSharp.Bindings/Bindings.Generated.cs"); var options = new CppParserOptions(); // TODO: test on macOS options.ConfigureForWindowsMsvc(CppTargetCpu.X86_64); options.AdditionalArguments.Add("-std=c++17"); CppCompilation compilation = CppParser.ParseFile(headerPath, options); if (compilation.DumpErrorsIfAny()) { Console.ReadKey(); return; } var mapper = new TypeMapper(compilation); mapper.RenamingForApi += (nativeName, isMethod) => { if (nativeName == "iterator") { return("ParsedJsonIteratorN"); } if (!isMethod) { return(nativeName + "N"); // SimdJsonSharp has two C# APIs: 1) managed 2) bindings - postfixed with 'N' } if (nativeName == "get_type") { return("GetTokenType"); } if (nativeName == "get_string") { return("GetUtf8String"); } return(nativeName); }; // init_state_machine requires external linkage (impl) mapper.RegisterUnsupportedMethod(null, "init_state_machine"); // Register native types we don't want to bind (or any method with them in parameters) mapper.RegisterUnsupportedTypes( "simdjson", // it's empty - we don't need it "__m128i", "simd_input", "utf8_checking_state", "basic_string", // TODO: "basic_string_view", // TODO "basic_ostream"); // TODO: var templateManager = new TemplateManager(); // Add additional stuff we want to see in the bindings.c templateManager .AddToCHeader(@"#include ""simdjson.h""") .AddToCHeader(@"using namespace simdjson;") .SetGlobalFunctionsClassName("SimdJsonN"); PinvokeGenerator.Generate(mapper, templateManager, @namespace: "SimdJsonSharp", dllImportPath: @"SimdJsonN.NativeLib", outCFile: cgluePath, outCsFile: bindingsPath); Console.WriteLine("Done."); }
public static unsafe void Main(string[] args) { // input (single header) string headerPath = Path.Combine(Environment.CurrentDirectory, "../../src/BindingsForNativeLib/SimdJsonNative/simdjson.h"); // output string cgluePath = Path.Combine(Environment.CurrentDirectory, "../../src/BindingsForNativeLib/SimdJsonNative/bindings.cpp"); string bindingsPath = Path.Combine(Environment.CurrentDirectory, "../../src/BindingsForNativeLib/SimdJsonSharp.Bindings/Bindings.Generated.cs"); var options = new CppParserOptions(); options.ConfigureForWindowsMsvc(CppTargetCpu.X86_64); options.EnableMacros(); options.AdditionalArguments.Add("-std=c++17"); // TODO: test on macOS CppCompilation compilation = CppParser.ParseFile(headerPath, options); var csSb = new StringBuilder(); csSb.AppendLine("// THIS FILE IS AUTOGENERATED!"); csSb.AppendLine(); csSb.AppendLine("using System;"); csSb.AppendLine("using System.Runtime.InteropServices;"); csSb.AppendLine(); csSb.Append($"namespace {Namespace}\n{{"); // Since we bind C++ we need to generate a DllImport-friendly C glue var cSb = new StringBuilder(); cSb.AppendLine("// THIS FILE IS AUTOGENERATED!"); cSb.AppendLine("#include \"simdjson.h\""); cSb.AppendLine(); cSb.AppendLine("#if (defined WIN32 || defined _WIN32)"); cSb.AppendLine("#define EXPORTS(returntype) extern \"C\" __declspec(dllexport) returntype __cdecl"); cSb.AppendLine("#else"); cSb.AppendLine("#define EXPORTS(returntype) extern \"C\" __attribute__((visibility(\"default\"))) returntype"); cSb.AppendLine("#endif"); List <CppClass> allClasses = compilation.GetAllClassesRecursively(); _allClassNames = allClasses.Select(c => c.GetDisplayName()).ToList(); foreach (CppClass cppClass in allClasses) { var csApiMethodsSb = new StringBuilder(); var csDllImportsSb = new StringBuilder(); string className = cppClass.Name; if (cppClass.Parent is CppClass parentClass) { className = $"{parentClass.Name}::{className}"; } if (_typesToIgnore.Contains(className)) { continue; } // prefix for all members string prefix = cppClass.Name + "_"; cSb.AppendLine(); cSb.AppendLine($"/* {className} */"); IEnumerable <CppFunction> allFunctions = cppClass.Constructors.Take(1 /* HACK: take only first available ctors for now :) */).Concat(cppClass.Functions); foreach (CppFunction cppFunc in allFunctions) { var argDefinitions = new List <string>(); var argInvocations = new List <string>(); // skip operators for now if (cppFunc.IsOperator()) { continue; } bool isStatic = cppFunc.StorageQualifier == CppStorageQualifier.Static; string funcPrefix = prefix; // Class_function() if (isStatic) { funcPrefix += "s_"; // Class_s_staticFunction() } if (!cppFunc.IsConstructor && !isStatic) { argDefinitions.Add($"{className}* target"); } foreach (CppParameter cppParam in cppFunc.Parameters) { var type = cppParam.Type.GetDisplayName(); // method contains a parameter of type we don't support - skip the whole method (goto) if (_typesToIgnore.Any(t => type.Contains(t))) { goto SKIP_FUNC; } string invocation = cppParam.Name; // HACK: replace references with pointers (for classes) if (type.EndsWith("&")) { type = type.Remove(type.Length - 1) + "*"; invocation = "*" + invocation; } argDefinitions.Add($"{type} {cppParam.Name}"); argInvocations.Add(invocation); } string funcReturnType = cppFunc.IsConstructor ? $"{className}*" : cppFunc.ReturnType.GetDisplayName(); string finalFuncName = $"{funcPrefix}{cppFunc.Name}"; // Func declaration cSb.Append($"EXPORTS({funcReturnType}) {finalFuncName}({argDefinitions.AsCommaSeparatedStr()})"); cSb.Append(" {"); // Body if (cppFunc.IsConstructor) { cSb.Append($" return new {className}({argInvocations.AsCommaSeparatedStr()});"); } else { string returnStr = cppFunc.ReturnType.IsVoid() ? " " : " return "; string invokeTarget = "target->"; if (isStatic) { invokeTarget = className + "::"; } cSb.Append($"{returnStr}{invokeTarget}{cppFunc.Name}({argInvocations.AsCommaSeparatedStr()});"); } cSb.Append(" }"); cSb.AppendLine(); var(dllImports, apiMethods) = GenerateMethodCSharp(cppFunc, finalFuncName); csDllImportsSb.AppendLine(dllImports); csApiMethodsSb.AppendLine(apiMethods); SKIP_FUNC: continue; } // destructor cSb.Append($"EXPORTS(void) {prefix}Dispose({className}* target) {{ delete target; }}"); cSb.AppendLine(); // generate C# for this method: csSb.AppendLine(GenerateClassCSharp(cppClass, csDllImportsSb.ToString(), csApiMethodsSb.ToString())); } csSb.Append("}"); // end of namespace File.WriteAllText(cgluePath, cSb.ToString()); File.WriteAllText(bindingsPath, csSb.ToString()); }