Formulaire C # de DLL chargé par C ++ natif

C’est une question qui découle de ce fil de discussion: C ++ natif utilise une dll C # via un proxy dll gérée C ++

En un mot, je charge (mon) extension C # dans un processus natif via une DLL. L’extension doit montrer un formulaire pour que l’utilisateur puisse le contrôler. J’utilise des formulaires .NET standard, pas de bibliothèques tierces ou quoi que ce soit, et mon formulaire n’apparaît pas. Pire encore, il bloque le processus cible. Il n’utilise aucun processeur, j’ai donc l’impression d’attendre le retour d’une fonction, mais ne le fait jamais.

Il est également intéressant de noter que la boîte de message “Méthode d’initialisation” apparaît, mais pas la boîte de message “Test”. J’ai testé tout ce à quoi je peux penser (STAthread, threads, DisableThreadLibraryCalls, ainsi que différents emplacements de code), dans tous les sens jusqu’à dimanche. Je suis enclin à penser que c’est un détail obscur de l’interopérabilité Win32, mais je ne trouve rien qui semble causer ces symptômes.

L’un de vous, experts, peut-il jeter un coup d’œil sur mon code et préciser le problème?

///  /// Provides entry points for native code ///  internal static class UnmanagedExports { [UnmanagedFunctionPointer(System.Runtime.InteropServices.CallingConvention.StdCall)] public delegate int SendRecv([MarshalAs(UnmanagedType.SafeArray)]byte[] ByteArray, UInt64 Len); [STAThread] [DllExport("Initialize", CallingConvention.StdCall)] public static int Initialize(IntPtr hInstance, SendRecv Send, SendRecv Recv) { return DLLinterface.Initialize(hInstance, Send, Recv); } [DllExport("Terminate", CallingConvention.StdCall)] public static void Terminate() { DLLinterface.Terminate(); } } internal class DLLinterface { static System.Threading.Thread uiThread; [STAThread] internal static int Initialize(IntPtr hInstance, UnmanagedExports.SendRecv Send, UnmanagedExports.SendRecv Recv) { MessageBox.Show("Initialize method"); try { uiThread = new System.Threading.Thread(Run); uiThread.Start(); } catch (Exception ex) { MessageBox.Show("Failed to load: " + ex.Message, "Infralissa error", MessageBoxButtons.OK, MessageBoxIcon.Error); } return 1; } [STAThread] private static void Run() { MessageBox.Show("Test"); Application.EnableVisualStyles(); Application.SetCompatibleTextRenderingDefault(false); Application.Run(new Form1()); } internal static void Terminate() { MessageBox.Show("Terminating."); if (uiThread.IsAlive) uiThread.Abort(); } } 

Il semble que la cible elle-même était en faute. Cela ne chargeait pas directement les extensions, mais plutôt un “exensionManager.dll” natif, où, comme par hasard, ils utilisaient DllMain pour charger MY. En d’autres termes, j’essayais de charger un formulaire sous loaderlock et je me suis retrouvé dans une impasse en tant que. NET a essayé de charger d’autres assemblys.

La réponse était simple, je devais montrer le formulaire sur un nouveau fil. Cependant, le threading de .NET était également suspendu, car il nécessitait également un chargement de bibliothèque bloqué.

À la fin, j’ai dû recourir à un P / Invoke à CreateThread () de vanille directement, mais le formulaire apparaît enfin.