加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

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

发布时间:2020-12-16 07:00:34 所属栏目:百科 来源:网络整理
导读:这个问题来自于这个主题: Native C++ use C# dll via proxy C++ managed dll 简而言之,我通过DLL将(我的)C#扩展加载到本机进程中.扩展程序需要显示一个表单,以便用户可以控制它.我正在使用标准的.NET表单,没有第三方图书馆或任何东西,我的表单没有出现.更糟
这个问题来自于这个主题: Native C++ use C# dll via proxy C++ managed dll

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

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

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

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

解决方法

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

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

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

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读