public static int EntryPoint(string arg) { _sharpScrobbler = new SharpScrobbler(); _sharpScrobblerGCHandle = GCHandle.Alloc(_sharpScrobbler); _managedExports = new ManagedExports { FreeManagedExports = FreeManagedExports, LogInfo = LogInfo, LogWarning = LogWarning, LogVerbose = LogVerbose, AskUserForNewAuthorizedSessionKey = _sharpScrobbler.AskUserForNewAuthorizedSessionKey, SetSessionKey = _sharpScrobbler.SetSessionKey, OnTrackCanScrobble = _sharpScrobbler.OnTrackCanScrobble, OnTrackStartsPlaying = _sharpScrobbler.OnTrackStartsPlaying, OnTrackCompletes = _sharpScrobbler.OnTrackCompletes, }; _managedExportsGCHandle = GCHandle.Alloc(_managedExports); // ManagedExports is not blittable, so we need a copy. // Making a copy in unmanaged memory from the managed side ensures the GC will not mess with it (I hope) _pManagedExports = Marshal.AllocHGlobal(Marshal.SizeOf(_managedExports)); Marshal.StructureToPtr(_managedExports, _pManagedExports, false); NativeImports.InitializeManagedExports(_pManagedExports); return(0); }
private static void FreeManagedExports() { Marshal.DestroyStructure <ManagedExports>(_pManagedExports); Marshal.FreeHGlobal(_pManagedExports); _managedExportsGCHandle.Free(); _sharpScrobblerGCHandle.Free(); _sharpScrobbler?.Dispose(); _sharpScrobbler = null; _sharpScrobblerGCHandle = default; _managedExports = null; _managedExportsGCHandle = default; _pManagedExports = default; }