不能 use/debug 来自 C# 的非托管 DLL

Can't use/debug unmanaged DLL from C#

我有一个 C# 应用程序和一个 C++ DLL,都是 x86。应用程序是启动项目,DLL 项目在同一解决方案中,并作为项目引用。 C++ DLL 在应用程序的调试文件夹中输出与 DLL 同名的 PDB 文件。

我有一个名为 SomeFunction 的函数,我试图在 C# 中执行它。当代码到达该行时,它就停在那里。 C# 应用程序的 UI 继续响应,但断点永远不会离开该行(并且在 Form_Load 中)。

如果我尝试将 DLL 设置为启动项目并告诉它执行 C# 应用程序,那么 C# 将在该行崩溃:System.EntryPointNotFoundException:无法找到名为 [=35= 的入口点] 在 DLL 'SomeDLL.dll'.

这是我要调用的函数的声明:

[DllImport("SomeDLL.dll", EntryPoint = "SomeFunction", CallingConvention = CallingConvention.Cdecl)]
public static extern int SomeFunction(IntPtr hwnd);

这是来自 C++ 头文件的函数声明:

#define MYDLL_API __declspec(dllexport)
MYDLL_API extern int SomeFunction(HWND hWnd);

这是我在 C# 中的调用方式:

var someAnswer = SomeFunction(_hwnd);

更新:由于下面的讨论可能需要一些时间才能阅读,所以简而言之就是答案:我缺少一个外部 "C"。此外,为了调试 DLL(这也是一个问题),该项目需要支持从 C++ 和 C# 进行本机调试,这是我经历过的一个很好的列表,最后一切都很好!

No Symbols loaded in mixed C# C(win32) project using VS2010

我怀疑它不会预先设置断点的问题是DLL是通过p-invoke按需加载的。如果 VS 认为 DLL 不是依赖项,它可能不允许您预先设置断点。

您可以将 DebugBreak 添加到您的 C++ 代码中。然后简单地 运行 你的应用程序,不要调试它。然后当它执行这个语句时,你会得到一个及时调试 警报,允许你跳转到 c++ 调试器。

C++ 作为启动

或者,您可以将 DLL 设为启动项目,但更改调试设置以使其启动外部进程 - 在本例中为您的应用程序 .exe。

然而这次,您不需要 DebugBreak(),只需一个常规断点。

现在,当您调试时,您的 DLL 符号会被加载,从而允许断点起作用。

我在 ActiveX/COM 中经常使用这个技巧。

  1. 运行 调用 SomeFunction 以确保加载非托管 .dll 的代码
  2. 进入调试 -> Windows -> 模块并检查 .dll 路径和 symbols 状态。您可以尝试在 window.
  3. 中的 c++ dll 的上下文菜单中加载 symbols

(.net 经常加载不同(非预期)版本的非托管 .dll)

现在我很确定问题出在您导出的函数名被破坏了。 尝试这样定义函数:

extern "C" MYDLL_API int PASCAL SomeFunction(HWND hWnd);

在 C# 中:

[DllImport("SomeDLL.dll")]
public static extern int SomeFunction(IntPtr hwnd);