来自本机C ++加载的DLL的C#表单

这个问题来自这个线程: Native C ++通过代理C ++管理的dll使用C#dll

简而言之,我通过DLL将(我的)C#扩展加载到本机进程中。 扩展程序需要显示一个表单,以便用户可以控制它。 我正在使用标准的.NET表单,没有第三方图书馆或任何东西,我的表单没有出现。 更糟糕的是,它挂起了目标进程。 它没有使用任何CPU,所以我感觉它等待某些function返回,但从来没有。

同样令人感兴趣的是弹出“初始化方法”消息框,但不弹出“测试”消息框。 我已经测试了我能想到的所有东西(STAthread,threads,DisableThreadLibraryCalls,加上不同的代码位置),每一个星期日。 我倾向于认为它是Win32互操作的一些模糊细节,但我找不到任何似乎会导致这些症状的东西。

你们其中一位专家可以查看我的代码并指出问题所在吗?

///  /// 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(); } } 

似乎目标本身是错误的。 它没有直接加载扩展,而是加载一个原生的“exensionManager.dll”,幸运的是,他们使用DllMain来加载我的扩展。 换句话说,我试图在加载器锁下加载一个表单并遇到死锁。 NET试图加载其他程序集。

答案很简单,我必须在新线程上显示表单。 但是,.NET的线程也悬而未决,因为它也需要一个陷入僵局的库加载。

最后,我不得不直接使用香草P / Invoke到CreateThread(),但表格最终出现了。