mono / CppSharp

Tools and libraries to glue C/C++ APIs to high-level languages
MIT License
3.14k stars 517 forks source link

Null Reference Exception during generation of code #1091

Open emmauss opened 6 years ago

emmauss commented 6 years ago
Brief Description

It throws null reference exception when it starts to generate code. I am parsing https://github.com/wjakob/nanogui, I can build and test it, so the generated libraries for parsing are available. I have set both the gui project and the parser project to build for x64. here is the parse log

C:\Program Files (x86)\Windows Kits\10\include\10.0.16299.0
Parsing libraries...
Parsing code...
Processing code...
Pass 'CppSharp.Passes.SortDeclarationsPass'
Pass 'CppSharp.Passes.ResolveIncompleteDeclsPass'
Pass 'CppSharp.Passes.IgnoreSystemDeclarationsPass'
Pass 'CppSharp.Passes.EqualiseAccessOfOverrideAndBasePass'
Pass 'CppSharp.Passes.CheckIgnoredDeclsPass'
Pass 'CppSharp.Passes.GenerateSymbolsPass'
Pass 'CppSharp.Passes.TrimSpecializationsPass'
Pass 'CppSharp.Passes.CheckIgnoredDeclsPass'
Pass 'CppSharp.Passes.CaseRenamePass'
Pass 'CppSharp.Passes.FunctionToInstanceMethodPass'
Pass 'CppSharp.Passes.FindSymbolsPass'
Pass 'CppSharp.Passes.CheckMacroPass'
Pass 'CppSharp.Passes.CheckStaticClass'
Pass 'CppSharp.Passes.MoveOperatorToClassPass'
Pass 'CppSharp.Passes.MoveFunctionToClassPass'
Pass 'CppSharp.Passes.ConstructorToConversionOperatorPass'
Pass 'CppSharp.Passes.MarshalPrimitivePointersAsRefTypePass'
Pass 'CppSharp.Passes.CheckAmbiguousFunctions'
Pass 'CppSharp.Passes.CheckOperatorsOverloadsPass'
Pass 'CppSharp.Passes.CheckVirtualOverrideReturnCovariance'
Pass 'CppSharp.Passes.CleanCommentsPass'
Pass 'CppSharp.Passes.CheckAbiParameters'
Pass 'CppSharp.Passes.FieldToPropertyPass'
Pass 'CppSharp.Passes.CleanInvalidDeclNamesPass'
Pass 'CppSharp.Passes.CheckIgnoredDeclsPass'
Pass 'CppSharp.Passes.CheckFlagEnumsPass'
Pass 'CppSharp.Passes.CheckDuplicatedNamesPass'
Pass 'CppSharp.Passes.GenerateAbstractImplementationsPass'
Pass 'CppSharp.Passes.MultipleInheritancePass'
Pass 'CppSharp.Passes.DelegatesPass'
Pass 'CppSharp.Passes.GetterSetterToPropertyPass'
Pass 'CppSharp.Passes.StripUnusedSystemTypesPass'
Pass 'CppSharp.Passes.SpecializationMethodsWithDependentPointersPass'
Pass 'CppSharp.Passes.ParamTypeToInterfacePass'
Pass 'CppSharp.Passes.MarkUsedClassInternalsPass'
Pass 'CppSharp.Passes.CaseRenamePass'
Generating code...

OS: Windows 10 1803

Used headers

from this https://github.com/wjakob/nanogui/tree/master/include/nanogui

Used settings

Library class

public class ParserLibrary : ILibrary
    {
        string IncludePath, LibPath;

        public ParserLibrary(string includePath, string libPath) : base()
        {
            IncludePath = includePath;
            LibPath = libPath;
        }

        public void Postprocess(Driver driver, ASTContext ctx)
        {

        }

        public void Preprocess(Driver driver, ASTContext ctx)
        {

        }

        public void Setup(Driver driver)
        {
            var options = driver.Options;
            options.GeneratorKind = GeneratorKind.CSharp;
            var module = options.AddModule("NanoGUI");
            module.IncludeDirs.Add(IncludePath);
            foreach (var dir in Directory.EnumerateDirectories(IncludePath))
            {
                module.IncludeDirs.Add(dir);
            }
            module.LibraryDirs.Add(LibPath);
            options.OutputDir = Path.Combine(Environment.CurrentDirectory, "out");
            options.Verbose = true;
            options.UseHeaderDirectories = true;
            module.LibraryName = "NanoGUI";
            module.OutputNamespace = "NanoGUI";
        }

        public void SetupPasses(Driver driver)
        {
            driver.Context.TranslationUnitPasses.RenameDeclsUpperCase(RenameTargets.Any);
            driver.Context.TranslationUnitPasses.AddPass(new FunctionToInstanceMethodPass());
        }
    }

Target: MSVC

Other settings

Stack trace or incompilable generated code
System.NullReferenceException: 'Object reference not set to an instance of an object.'
   at CppSharp.AST.TranslationUnit.get_FileRelativeDirectory()
   at CppSharp.Driver.SaveCode(IEnumerable`1 outputs)
   at CppSharp.ConsoleDriver.Run(ILibrary library)
   at CppWrapper.Program.Main(String[] args) in C:\Users\Emmanuel Hansen\Documents\Visual Studio 2017\Projects\CppParser\CppParser\Program.cs:line 32
tritao commented 6 years ago

Problem is only when saving the generated code, so it looks like its processing and generating the bindings correctly.

I noticed your working path has spaces, maybe check if that makes any difference.

If not, please compile with master and check in the debugger why CppSharp.AST.TranslationUnit.get_FileRelativeDirectory is null.

emmauss commented 6 years ago

i will try with the debugger

emmauss commented 6 years ago

i have built the cppsharp library, but when I reference it in my project, I get this System.IO.FileNotFoundException: 'Could not load file or assembly 'CppSharp.Parser.CLI.dll' or one of its dependencies. The specified module could not be found. stacktrace at CppSharp.ConsoleDriver.Run(ILibrary library) at CppWrapper.Program.Main(String[] args) in C:\Users\Emmanuel Hansen\Documents\Visual Studio 2017\Projects\CppParser\CppParser\Program.cs:line 42 i have set the solution to build with x86 and release configuration I have referenced CppSharp.Parser.CLI and the other porjects that would have been added in the nuget package

tritao commented 6 years ago

You need to copy CppSharp.CppParser.dll next to your executable.

emmauss commented 6 years ago

it now run. this is the exception

System.NullReferenceException: 'Object reference not set to an instance of an object.' IncludePath was null.

stacktrace

  at CppSharp.AST.TranslationUnit.get_FileRelativeDirectory() in C:\Users\Emmanuel Hansen\CppSharp-master\CppSharp-master\src\AST\TranslationUnit.cs:line 66
   at CppSharp.Driver.SaveCode(IEnumerable'1 outputs) in C:\CppSharp-master\CppSharp-master\src\Generator\Driver.cs:line 304
   at CppSharp.ConsoleDriver.Run(ILibrary library) in C:\CppSharp-master\CppSharp-master\src\Generator\Driver.cs:line 459
   at CppWrapper.Program.Main(String[] args) in C:\Users\Emmanuel Hansen\Documents\Visual Studio 2017\Projects\CppParser\CppParser\Program.cs:line 42
emmauss commented 6 years ago

any help on this?

tritao commented 6 years ago

https://github.com/mono/CppSharp/blob/b44546bdd041a0e54376fc6b34365281bbda39ee/src/Generator/Passes/CleanUnitPass.cs#L19

This is where we set IncludePath for translation units. Presumably GetIncludePath() fails for some translation units on your binding.

Can you add a breakpoint there and figure out if that is the case and why?

emmauss commented 6 years ago
@tritao I did it, but it never failed. I check the unit data at the exception break point, it gave me this `  Name Value Type
this File = "Std.cs", Ignored = false CppSharp.AST.TranslationUnit`

I don't know where Std.cs is. Its file path is the same as its name.