/// <summary> /// Code taken from Vlc.DotNet /// </summary> /// <param name="data"></param> /// <param name="level"></param> /// <param name="ctx"></param> /// <param name="format"></param> /// <param name="args"></param> void OnLogInternal(IntPtr data, LogLevel level, IntPtr ctx, string format, IntPtr args) { if (_log == null) { return; } // Original source for va_list handling: https://stackoverflow.com/a/37629480/2663813 var byteLength = MarshalUtils.Vscprintf(format, args) + 1; var utf8Buffer = Marshal.AllocHGlobal(byteLength); string formattedDecodedMessage; try { MarshalUtils.Vsprintf(utf8Buffer, format, args); formattedDecodedMessage = (string)Utf8StringMarshaler.GetInstance().MarshalNativeToManaged(utf8Buffer); } finally { Marshal.FreeHGlobal(utf8Buffer); } GetLogContext(ctx, out var module, out var file, out var line); // Do the notification on another thread, so that VLC is not interrupted by the logging #if NET40 Task.Factory.StartNew(() => _log?.Invoke(NativeReference, new LogEventArgs(level, formattedDecodedMessage, module, file, line))); #else Task.Run(() => _log?.Invoke(NativeReference, new LogEventArgs(level, formattedDecodedMessage, module, file, line))); #endif }