2012-07-03 56 views
4

這本主題中產生的問題,加載:通過DLL Native C++ use C# dll via proxy C++ managed dllC#的形式通過本地C++

概括地說,我加載(我的)C#擴展到本機進程。該擴展需要顯示一個表單,以便用戶可以控制它。我使用的是標準的.NET表單,沒有第三方庫或任何東西,我的表單沒有顯示出來。更糟糕的是,它掛起了目標進程。它沒有使用任何CPU,所以我感覺它等待一些函數返回,但從來沒有。

另外感興趣的是彈出「Initialize method」消息框,但不彈出「Test」消息框。我已經測試了所有我能想到的東西(STAthread,線程,DisableThreadLibraryCalls,以及不同的代碼位置),每個星期天都有。我傾向於認爲這是Win32 interop的一些不爲人知的細節,但我找不到任何似乎會導致這些症狀的東西。

你們的專家可以看看我的代碼並指出問題是什麼嗎?

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

+1。 'DllExport'對我來說是新的。谷歌搜索,發現這是由一些IL黑客完成。我想知道CLR運行時如何以及何時加載。希望有人能回答你的問題。 –

+0

DllExport對我來說也是新的。它看起來非常強大,我無法想象爲什麼微軟還沒有輕鬆實現。對於你關於CLR加載的問題,我查看了自動生成的DllMain,看起來就是加載了clr的地方。 DllMain是編譯器生成的,所以你無法控制它。 – Xcelled194

+0

只有你可能會嘗試的技巧是選擇「Embed Interop Types」來嘗試管理Windows窗體的靜態鏈接,但它可能不起作用。對於您的應用程序,最好從.NET應用程序開始,然後打開本機窗口。 – weismat

回答

1

看起來目標本身有問題。它沒有直接加載擴展,而是加載了一個本地的「expportManager.dll」,如果幸運的話,他們會使用DllMain來加載我的擴展。換句話說,我試圖在loaderlock下加載一個表單,並且陷入了僵局。 NET試圖加載其他程序集。我不得不在一個新的線程上顯示窗體。然而,.NET的線程也是懸而未決的,因爲它也需要一個死鎖的庫加載。最後,我不得不直接訴諸一個vanilla P/Invoke到CreateThread(),但表單終於出現了。