从DLL C#的形式通过本地C ++装 [英] C# form from DLL loaded by native C++

查看:96
本文介绍了从DLL C#的形式通过本地C ++装的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

这本主题中出现的一个问题:的本机C ++通过代理C ++托管DLL



使用C#DLL概括地说,我加载通过DLL(我的)C#扩展到本机进程。扩展需要显示一个表格,以使用户可以控制它。我使用的是标准的.NET的形式,没有第三方图书馆的或任何东西,我的表格没有显示出来。更糟糕的是,它挂起目标进程。它不使用任何CPU,所以我得到了等待一些函数返回的感觉,但从来不会。



同样有趣的是,初始化方法的消息框弹出,而不是测试的消息框。我测试过的一切我能想到的(STAthread,线程,DisableThreadLibraryCalls,再加上不同的代码的位置),每路至周日。我倾向于认为这是Win32的互操作的一些不起眼的细节,但我无法找到任何东西,似乎引起这些症状。



您的专家之一可乘坐?看看我的代码,并指出问题是什么

  ///<总结> 
///提供切入点本地代码
///< /总结>
内部静态类UnmanagedExports
{
[UnmanagedFunctionPointer(System.Runtime.InteropServices.CallingConvention.StdCall)
公共委托INT SENDRECV([的MarshalAs(UnmanagedType.SafeArray)字节[ ]字节数组,UINT64 LEN);

[STAThread]
[DLLEXPORT(初始化,CallingConvention.StdCall)]
公共静态INT初始化(IntPtr的实例句柄,SENDRECV发送,SENDRECV RECV)
{
返回DLLinterface.Initialize(实例句柄,发送,RECV);
}

[DLLEXPORT(终止,CallingConvention.StdCall)]
公共静态无效的终止()
{
DLLinterface.Terminate();
}
}

内部类DLLinterface
{
静态System.Threading.Thread uiThread;

[STAThread]
内部静态初始化INT(IntPtr的实例句柄,UnmanagedExports.SendRecv发送,UnmanagedExports.SendRecv RECV)
{
MessageBox.Show(初始化方法 );

{
uiThread =新System.Threading.Thread(运行);
uiThread.Start();
}
赶上(异常前)
{
MessageBox.Show(无法加载:+ ex.Message,Infralissa错误,MessageBoxButtons.OK,MessageBoxIcon.Error );
}
返回1;
}

[STAThread]
私有静态无效的run()
{
MessageBox.Show(测试);

Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(假);
Application.Run(新Form1中());
}

内部静态无效终止()
{
MessageBox.Show(终止);
如果(uiThread.IsAlive)
uiThread.Abort();
}
}


解决方案

据看来这个目标本身是有过错的。它不直接加载扩展,而是装载本地exensionManager.dll,在这里,因为幸运的是,他们使用的DllMain加载了我的扩展。换句话说,我试图负载下loaderlock形式,撞上了僵局的。 NET试图加载其他组件。



答案很简单,我不得不显示在一个新线程的形式。然而,.NET的线程也被挂,因为它也需要这僵持的库负载。



在最后,我不得不求助于香草的P / Invoke到的CreateThread()直接,但形式终于显示出来。


This a question arising from this thread: Native C++ use C# dll via proxy C++ managed dll

In a nutshell, I'm loading (my) C# extension into a native process via a DLL. The extension needs to show a form so that the user can control it. I'm using standard .NET forms, no 3rd party librarys or anything, and my form is not showing up. Worse yet, it hangs the target process. It's not using any CPU, so I get the feeling its waiting for some function to return, but never does.

Also of interest is that the "Initialize method" message box pops up, but not the "Test" message box. I've tested everything I can think of (STAthread, threads, DisableThreadLibraryCalls, plus different code locations), every way to Sunday. I'm inclined to think it's some obscure detail of Win32 interop, but I can't find anything that would seem to cause these symptoms.

Can one of you experts take a look at my code and point out what the issue is?

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

解决方案

It seems that the target itself was at fault. It wasn't loading the extensions directly, but instead loading a native "exensionManager.dll", where, as luck would have it, they were using DllMain to load up MY extension. In other words, I was trying to load a form under loaderlock and ran into a deadlock as. NET tried to load other assemblies.

The answer was simple, I had to show the form on a new thread. However, .NET's threading was also hanging, as it, too, required a library load which deadlocked.

In the end, I had to resort to a vanilla P/Invoke to CreateThread() directly, but the form is finally showing up.

这篇关于从DLL C#的形式通过本地C ++装的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆