【问题标题】:Exception when closing a Win32 dialog box in dll (from WPF application)在 dll 中关闭 Win32 对话框时出现异常(来自 WPF 应用程序)
【发布时间】:2017-04-14 11:25:51
【问题描述】:

我有一个从 DLL 调用 C++ 函数的 C# 应用程序。 C++ 函数只显示一个对话框和一个退出按钮。

DLL 中的 C++ 函数如下所示:

//the exported function for clients to call in DLL
HINSTANCE hInstance;
__declspec(dllexport) int __cdecl StartDialog(string inString)
{
    hInstance = LoadLibrary(TEXT("My.dll"));
    DialogBox(hInstance, MAKEINTRESOURCE(ID_DLL_Dialog), NULL, DialogProc);
    return 1;
}

BOOL CALLBACK DialogProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
    switch (message)
    {
    case WM_COMMAND:
        switch (LOWORD(wParam))
        {
        case IDD_BUTTON_EXIT:
            DestroyWindow(hwnd);
            return TRUE;            
        }
    }
    return FALSE;
}

如果我在一个简单的 C++ 程序中调用我的 StartDialog 函数,它就可以工作。我可以显示对话框,当我在对话框中单击退出时可以正确关闭它。

typedef int(__cdecl *StartDialogFunc)(string);
StartDialogFunc StartDialog = nullptr;
HINSTANCE hDll = LoadLibrary(TEXT("My.dll"));
StartDialog = (StartDialogFunc)GetProcAddress(hDll, "StartDialog");

int i = StartDialog("hello");    //this is working
cout << i;

如果我在我的 C# 应用程序中调用它,在我单击退出按钮后,对话框将关闭,并给我一个异常。 C# 代码如下所示:

[DllImport("My.dll", CallingConvention = CallingConvention.Cdecl)]
public static extern int StartDialog(string s);

int i = StartDialog("hello");    //this causes a exception

错误信息如下:

调试断言失败!

程序:(一些路径...)My.dll

文件:d:\program files (x86)\microsoft visual studio 14.0\vc\include\xmemory0

行:100

表达式:“(_Ptr_user & (_BIG_ALLOCATION_ALIGNMENT - 1)) == 0” && 0

有关您的程序如何导致断言失败的信息,请参阅有关断言的 Visual C++ 文档。

我如何知道我的 DLL 中到底出了什么问题?

【问题讨论】:

  • 尝试更改 C++ 函数签名以采用 WCHAR*,因为 C++ 的 string 与 C# 不兼容。此外,要获取当前 DLL 的句柄,请使用 GetModuleHandle(NULL),而不是 LoadLibrary。
  • 叮叮叮,user1610015在所有方面都完全正确。 CLR 不能将 String 对象封送为 C++ std::string 对象。 @user1610015,请考虑将您的评论升级为答案。
  • @CodyGray 确定

标签: c# c++ wpf dll


【解决方案1】:

尝试更改 C++ 函数签名以采用 WCHAR*,因为 C++ 的 std::string 与 C# 不兼容。此外,要获取当前 DLL 的句柄,请使用 GetModuleHandle(NULL),而不是 LoadLibrary。

HINSTANCE hInstance;

__declspec(dllexport) int __cdecl StartDialog(const WCHAR* inString)
{
    hInstance = GetModuleHandle(NULL);
    DialogBox(hInstance, MAKEINTRESOURCE(ID_DLL_Dialog), NULL, DialogProc);
    return 1;
}

【讨论】:

  • 太棒了!一个 char 数组正在为我工​​作。但是hInstance = GetModuleHandle(NULL); 不起作用,但我的旧方法有效。
  • 没错,直到现在我才知道这一点,但 GetModuleHandle(NULL) 返回的是 EXE 的句柄而不是 DLL。正如这个(stackoverflow.com/questions/119706/… 答案所说,正确的解决方案是编写一个 DllMain 函数并将 hInstance 参数存储到全局变量中。
  • 谢谢。现在我成功地从我的 Dll 主函数中获得了 HINSTANCE。
猜你喜欢
  • 2012-04-29
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-10-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多