Access Violation when using 2.0.16 w/ .NET

I’m pretty sure this is probably a case of me just doing something stupid, but I’ve been staring at this code for the better part of a couple of hours and made no progress. Another pair of eyes would be greatly appreciated.

The issue I’m having is when I call “Astra.StreamSet.Open($“device/sensor{index}”)” I’m getting an access violation exception. The stack trace for the exception is here:

at Astra.Bindings.Imports.astra_streamset_open(String connectionString, IntPtr& streamSetHandle)
at Astra.Core.Native.StreamSet.Open(String connectionString)
at Astra.StreamSet.Open(String connectionString)
at [redacted].Cameras.AstraCamera..ctor(Int32 index) in [redacted]\Cameras\AstraCamera.cs:line 23
at [redacted].Cameras.AstraCamera.GetDefault() in [redacted]\Cameras\AstraCamera.cs:line 31
...

My application is compiled for AnyCPU, so I’ve included the 32- and 64-bit version is Astra/win32 and Astra/win64 directories, and added an assembly resolver to load the correct DLLs. The Astra folder itself is included in the output directory, and the reference to AstraDotNet in my class library has “Copy Local” set to false. Similarly, my application does not have the “Prefer 32 Bit” option enabled.

The code for the assembly resolver is:

public static class AssemblyResolver
{
    public static void Initialize(AppDomain appDomain = null)
    {
        if (appDomain == null)
            appDomain = AppDomain.CurrentDomain;
        appDomain.AssemblyResolve += HandleAssemblyResolve;
    }

    private class AssemblyTarget
    {
        public string AssemblyName { get; set; }
        public string Directory { get; set; }
        public string SubDir32 { get; set; }
        public string SubDir64 { get; set; }
    }

    private static readonly List<AssemblyTarget> Targets = new List<AssemblyTarget>()
    {
        new AssemblyTarget()
        {
            AssemblyName = "AstraDotNet",
            Directory = "Astra",
            SubDir32 = "win32",
            SubDir64 = "win64"
        }

        // Add any additional architecture-reliant assemblies here
    };

    private static Assembly HandleAssemblyResolve(object sender, ResolveEventArgs args)
    {
        if (args.Name != null
            && args.Name.IndexOf(".resources,", StringComparison.InvariantCultureIgnoreCase) < 0)
        {
            foreach(AssemblyTarget target in Targets)
            {
                if(args.Name.StartsWith(target.AssemblyName, StringComparison.InvariantCultureIgnoreCase))
                {
                    var appDomain = (AppDomain)sender;
                    var path = Path.Combine(appDomain.BaseDirectory, target.Directory, Environment.Is64BitProcess ? target.SubDir64 : target.SubDir32);
                    path = Path.Combine(path, target.AssemblyName + ".dll");
                    if (File.Exists(path))
                        return Assembly.LoadFrom(path);
                }
            }
        }

        return null;
    }
}

And the code for the AstraCamera constructor is super basic:

public AstraCamera(int index=0)
{
    Streams = Astra.StreamSet.Open($"device/sensor{index}");
    Reader = Streams.CreateReader();
}

public static AstraCamera GetDefault()
{
    if(_uniqueInstance == null)
    {
        _uniqueInstance = new AstraCamera();
    }
    return _uniqueInstance;
}
private static AstraCamera _uniqueInstance;

I double-checked that I had the 32- and 64-bit versions of the SDK in the correct folders. I tried compiling for 32- and 64-bit architectures instead of AnyCPU. I tried removing the parameter from StreasmSet.Open() just in case the issue was with the index.

The order of execution for the seemingly-relevant parts are:

  1. Initialize the Assembly Resolver (I checked, and this is definitely happening before the constructor is called, and the path to AstraDotNet.dll appears to be correct)
  2. Open the main window
  3. In the main window’s load function, create a new instance of AstraCamera, which is a wrapper for the AstraSDK that implements some specific interfaces my application needs. This is done using the AstraCamera.GetDefault() function from above.

It’s crashing in step 3.

The problem is not with the libraries themselves; I copied the new Astra/* folder into another application I have that used an older version of the SDK, and it worked fine there. So it’s something specific to this application, but for the life of me I can’t figure out what I’ve missed.

Insert facepalm here: I forgot to call Astra.Context.Initialize().

I knew I was doing something stupid. At least I figured out what it was. Let this be a lesson to any future developers.