2010-01-16 4 views
1

У меня есть решение Visual Studio 2008 с двумя проектами: приложение C# Windows Forms и C++ DLL. DLL открывает пользовательский CFileDialog. Вот это игрушка версия, которая демонстрирует проблему, где # приложение C только кнопка для запуска диалога и метку, чтобы показать свой результат:Откройте диалоговое окно из DLL

DialogApp.cs:

... 
public partial class Form1 : Form { 
    ... 
    [DllImport("DialogDll.dll")] 
    static extern int OpenDialog(); 
    ... 
    private void button1_Click(object sender, EventArgs e) { 
     int r = OpenDialog(); 
     label1.Text = r.ToString(); 
    } 
} 

DialogDll.h:

extern "C" { 
    __declspec(dllexport) int __cdecl OpenDialog(); 
} 

DialogDll.cpp:

#include <afxdlgs.h> 
#include "DialogDll.h" 

extern int __cdecl OpenDialog() { 
    CFileDialog d(TRUE, NULL, NULL, OFN_HIDEREADONLY, _T("All Files (*.*)|*.*||"), NULL); 
    if (d.DoModal() == IFOK) { 
     return 4; 
    } else { 
     return 9; 
    } 
} 

Когда я запускаю это, я получаю ошибку о отладки утверждают ион не работает, попросив Abort | Retry | Ignore. Утверждение afxCurrentResourceHandle != NULL. Как мне избавиться от этой проблемы? Если я нажму «Игнорировать», я получу свой диалог, и все будет работать нормально.

Я уже пробовал, следуя инструкциям здесь: http://msdn.microsoft.com/en-us/library/7a51wcfx.aspx

Эти направления говорят, что проблема в том, что DLL не имеет объекта CWinApp, и я должен добавить AFX_MANAGE_STATE(AfxGetStaticModuleState()) в начале каждого вызова функции. Я сделал это и должен был решить проблему с компоновщиком, следуя указаниям здесь, вручную указав точку входа для моей DLL: http://social.msdn.microsoft.com/forums/en-US/vcgeneral/thread/0b154e1c-141f-4567-bb24-1ac7c8ee2713/ (Детали об изменении порядка .libs не работали для меня.)

Но теперь я получаю еще одну ошибку:

LoaderLock was detected: 
Attempting managed execution code inside OS Loader Lock. Do not attempt to run 
managed code inside a DllMain or image initialization function since doing so 
can cause the application to hang. 

Хорошее горе! Я даже иду в правильном направлении? Я много лет программировал, но я довольно новичок в платформе Windows. Я думаю, что после всей этой работы мой вопрос все еще довольно прост: как мне открыть CFileDialog из моей dll?

+0

Если вы добавили вызов AFX_MANAGE_STATE к вашей DllMain, может удалить его? Вызываемый управляемый код, вероятно, является обработчиком событий для окна C#, вызываемого через вызов в DispatchMessage в контуре сообщения где-то. –

+0

Я вообще не написал DllMain. –

+0

Итак, Пол, вы нашли решение этой проблемы? – sizzle

ответ

-1

Пожалуйста, смотрите комментарий выше, но я бы рекомендовал, как мой ответ:

Используйте System.Windows.Forms.OpenFileDialog вместо ИЛИ

Использование GetOpenFileName

+0

Существующие функции C# для открытия диалогового окна не работают для меня. Мне нужен доступ к моей собственной реализации на C++. –

0

Вы, вероятно, идет в правильном направлении. Я предполагаю, что вы хотите/должны использовать MFC в своей DLL.

Рекомендации WinApp и MANAGE_STATE были хорошими.

Вы бросаете/clr или/clr: чистые на любом из ваших исходных файлов на C++? Зачем? Совместим ли ваш C++ DLL-mix и собственный код?

Исправление для этого тривиального приложения - не бросать/clr. Это сделает ваш код на C++ родным и гарантирует, что вы не рискуете вызвать управляемые статические инициализаторы из блокировки загрузчика.

Martyn

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