代码之家  ›  专栏  ›  技术社区  ›  Paul A Jungwirth Mathew Sachin

从DLL打开对话框

  •  1
  • Paul A Jungwirth Mathew Sachin  · 技术社区  · 16 年前

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

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

    对话框dll.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;
        }
    }
    

    当我运行这个程序时,我得到一个关于调试断言失败的错误,请求中止|重试|忽略。断言是 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平台还是比较陌生的。我想在完成了所有这些工作之后,我的问题仍然很简单:如何从dll打开CFileDialog?

    2 回复  |  直到 16 年前
        1
  •  0
  •   Martyn Lovell    15 年前

    你的方向可能是对的。我假设你想/需要在DLL中使用MFC。

    WinApp和MANAGE_STATE的建议很好。

    你是在投掷/清除还是/clr:纯启用你的C++源文件有哪些?为什么?您的C++ DLL是否将托管代码和本机代码混合在一起?

    这个小应用的修复方法是不抛出/clr。这将使所有C++代码原生,并确保您不必从加载程序锁调用托管静态初始化器。

        2
  •  -1
  •   Dark Falcon    16 年前

    请参阅上面的评论,但我建议作为我的回答:

    使用 System.Windows.Forms.OpenFileDialog 或者

    使用 GetOpenFileName