public static Task <int> RunAsync( string[] args, Func <string[], QCoreApplication, QQmlApplicationEngine, NetRunCallbackDelegate, Task <int> > action) { return(Task.FromResult(Run(args, (argsInner, application, engine, callback) => { var result = action(argsInner, application, engine, callback); bool completed = false; var task = Task.Run(() => { var exitCode = -1; try { exitCode = result.GetAwaiter().GetResult(); } finally { completed = true; } return exitCode; }); while (!completed) { QCoreApplication.ProcessEvents(QEventLoop.ProcessEventsFlag.EventLoopExec | QEventLoop.ProcessEventsFlag.WaitForMoreEvents); } return task.GetAwaiter().GetResult(); }))); }
public static int Run(string[] args, Func <string[], QCoreApplication, QQmlApplicationEngine, NetRunCallbackDelegate, int> action) { if (args.Length < 4) { throw new Exception("Args is invalid, must contain three entries which are pointers to native types."); } var appPtr = new IntPtr((long)ulong.Parse(args[0])); var enginePtr = new IntPtr((long)ulong.Parse(args[1])); var callbackPtr = new IntPtr((long)ulong.Parse(args[2])); var exportedSymbolPtr = new IntPtr((long)ulong.Parse(args[3])); GetExportedSymbol = Marshal.GetDelegateForFunctionPointer <GetExportedSymbolDelegate>(exportedSymbolPtr); QCoreApplication app = null; switch (Interop.QCoreApplication.GetAppType(IntPtr.Zero, appPtr)) { case 0: app = new QCoreApplication(appPtr); break; case 1: app = new QGuiApplication(appPtr); break; case 2: app = new QApplication(appPtr); break; default: throw new Exception("Invalid app type"); } using (app) { using (var engine = new QQmlApplicationEngine(enginePtr)) { var runCallback = new NetRunCallbackDelegate(() => { var callback = Marshal.GetDelegateForFunctionPointer <NativeRunCallbackDelegate>(callbackPtr); // ReSharper disable AccessToDisposedClosure return(callback.Invoke(app.InternalPointer, engine.InternalPointer)); // ReSharper restore AccessToDisposedClosure }); return(action(args.Skip(2).ToArray(), app, engine, runCallback)); } } }