首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >由本机C++加载的来自DLL的C#表单

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

Stack Overflow用户
提问于 2012-07-03 11:28:02
回答 1查看 1.5K关注 0票数 5

这是由这个帖子引起的问题:Native C++ use C# dll via proxy C++ managed dll

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

同样有趣的是弹出"Initialize method“消息框,而不是"Test”消息框。我已经测试了我能想到的所有东西(STAthread,线程,DisableThreadLibraryCalls,加上不同的代码位置),每种方法都到了星期天。我倾向于认为这是Win32互操作的一些晦涩难懂的细节,但我找不到任何可能导致这些症状的东西。

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

代码语言:javascript
运行
复制
/// <summary>
/// Provides entry points for native code
/// </summary>
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();
   }
}
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2012-07-04 12:17:59

似乎是目标本身有错。它没有直接加载扩展,而是加载了一个本机"exensionManager.dll",幸运的是,他们使用DllMain加载了我的扩展。换句话说,我试图在loaderlock下加载一个表单,却遇到了死锁。NET尝试加载其他程序集。

答案很简单,我必须在一个新的线程上显示表单。然而,.NET的线程也挂起了,因为它也需要一个死锁的库加载。

最后,我不得不直接求助于对CreateThread()的普通P/Invoke,但是表单终于出现了。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/11304072

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档