2012-07-03 2 views
4

Этот вопрос, возникающий из этой темы: Native C++ use C# dll via proxy C++ managed dllC# формы из DLL загружается родной C++

В двух словах, я загружаю (мой) C# расширение в родной процесс через DLL. Расширение должно показать форму, чтобы пользователь мог ее контролировать. Я использую стандартные формы .NET, нет сторонних библиотек или что-то еще, и моя форма не появляется. Хуже того, он висит в целевом процессе. Он не использует какой-либо процессор, поэтому я чувствую, что его ждут возврата какой-то функции, но никогда этого не делает.

Также интересно, что появляется окно сообщения «Инициализировать метод», но не окно сообщения «Тест». Я тестировал все, о чем я могу думать (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(); 
    } 
} 
+0

+1 о проблеме. 'DllExport' для меня новичок. Был ли поиск в Google и нашел, что это сделано некоторым взломом IL. Интересно, как и когда загрузилась среда CLR. Надеюсь, кто-то может ответить на ваш вопрос. –

+0

DllExport также новичок со мной. Он выглядит довольно мощным, и я не могу себе представить, почему Microsoft не сделала его доступным. На ваш вопрос о загрузке CLR я заглянул в автогенератор DllMain, и похоже, что там загружается clr. DllMain генерируется компилятором, поэтому вы не контролируете его. – Xcelled194

+0

Только трюк, который вы можете попробовать, это выбрать «Вставить типы взаимодействия», чтобы попытаться управлять статическим связыванием для форм Windows, но это может не сработать. Для вашего приложения лучше начать с приложения .NET и открыть потом собственные окна. – weismat

ответ

1

Похоже, что цель была виновата. Он не загружал расширения напрямую, а вместо этого загружал собственный «exensionManager.dll», где, как повезло, они использовали DllMain для загрузки MY расширения. Другими словами, я пытался загрузить форму под loaderlock и столкнулся с тупиком. NET попытался загрузить другие сборки.

Ответ был прост, мне пришлось показать форму на новой теме. Однако потоки .NET также зависали, так как это тоже требовало загрузки библиотеки, которая зашла в тупик.

В конце концов, мне пришлось прибегать к ванильному P/Invoke to CreateThread(), но форма, наконец, появляется.

Смежные вопросы