在 Visual Studio 中调试 DLL(C#、C++、Visual Basic、F#)

DLL(动态链接库)是一个库,其中包含多个应用可以使用的代码和数据。 可以使用 Visual Studio 创建、生成、配置和调试 DLL。

创建 DLL

以下 Visual Studio 项目模板可以创建 DLL:

  • 类库(.NET、.NET Framework 和其他应用平台)
  • Windows 窗体控件库(.NET 和 .NET Framework)
  • Dynamic-Link 库 (DLL) (C++)

调试 Windows 窗体控件库类似于调试类库。 有关详细信息,请参阅 Windows 窗体控件

通常从另一个项目调用 DLL。 调试调用项目时,根据 DLL 配置,可以单步跟踪和调试 DLL 代码。

DLL 调试配置

使用 Visual Studio 项目模板创建应用时,Visual Studio 会自动创建调试和发布生成配置所需的设置。 如有必要,可以更改这些设置。 如需了解更多信息,请参阅以下文章:

设置 C++ DebuggableAttribute

若要使调试器附加到 C++ DLL,C++ 代码必须发出 DebuggableAttribute

要设置 DebuggableAttribute

  1. 解决方案资源管理器 中选择C++ DLL 项目,然后选择 “属性” 图标,或右键单击该项目并选择“ 属性”。

  2. “属性”窗格中的“链接器>调试”下,为可调试程序集选择“是”(/ASSEMBLYDEBUG)。

有关详细信息,请参阅 /ASSEMBLYDEBUG

设置 C/C++ DLL 文件位置

若要调试外部 DLL,调用项目必须能够找到 DLL、其 .pdb 文件以及 DLL 所需的任何其他文件。 可以创建自定义生成任务,将这些文件复制到 <项目文件夹>\调试 输出文件夹,也可以手动复制文件。

对于 C/C++项目,可以在项目属性页中设置标头和 LIB 文件位置,而不是将它们复制到输出文件夹。

若要设置 C/C++ 标头和 LIB 文件位置,请执行以下作:

  1. 解决方案资源管理器 中选择 C/C++ DLL 项目,然后选择 “属性” 图标,或右键单击该项目并选择“ 属性”。

  2. 在“ 属性 ”窗格顶部的 “配置”下,选择“ 所有配置”。

  3. C/C++>General>其他包含目录下,指定包含头文件的文件夹。

  4. “链接器>常规>其他库目录”下,指定具有 LIB 文件的文件夹。

  5. “链接器>输入>其他依赖项”下,指定 LIB 文件的完整路径和文件名。

  6. 选择“确定”

有关C++项目设置的详细信息,请参阅 Windows C++ 属性页参考

生成调试版本

在开始调试之前,请确保生成 DLL 的调试版本。 若要调试 DLL,调用应用必须能够找到其 .pdb 文件和 DLL 所需的任何其他文件。 有关详细信息,请参阅 “如何:设置调试和发布配置”。

可以创建自定义生成任务,将 DLL 文件复制到 <调用项目文件夹>\调试 输出文件夹,也可以手动复制文件。

请确保调用位于正确位置的 DLL。 这似乎是显而易见的,但如果调用应用找到并加载 DLL 的不同副本,调试器永远不会命中设置的断点。

调试 DLL

无法直接运行 DLL。 它必须由应用(通常是 .exe 文件)调用。

若要调试 DLL,可以从 调用应用开始调试,也可以通过指定 DLL 项目的调用应用进行 调试 。 还可以使用调试器 即时窗口 在设计时评估 DLL 函数或方法,而无需使用调用应用。

从调用应用启动调试

调用 DLL 的应用可以是:

  • Visual Studio 项目中与 DLL 在同一或不同解决方案中的应用。
  • 已在测试或生产计算机上部署和运行的现有应用。
  • 位于 Web 上并通过 URL 访问。
  • 包含嵌入 DLL 的网页的 Web 应用。

在开始调试调用应用之前,在 DLL 中设置断点。 请参阅 断点入门。 DLL 断点命中时,可以单步跟踪代码,观察每个行的操作。 有关详细信息,请参阅 调试器中的 Navigate 代码

从调用应用程序调试 DLL,你可以:

  • 打开调用应用的项目,然后选择 “调试>开始调试 ”或按 F5 开始调试。

  • 连接到已在测试或生产计算机上部署和运行的应用程序。 将此方法用于网站或 Web 应用中的 DLL。 有关详细信息,请参阅 “如何:附加到正在运行的进程”。

在调试期间,可以使用“ 模块 ”窗口来验证应用加载的 DLL 和 .exe 文件。 若要在调试时打开 “模块 ”窗口,请选择“ 调试>Windows>模块”。 有关详细信息,请参阅 “如何:使用模块”窗口

使用“即时”窗口

可以使用 “即时 ”窗口在设计时评估 DLL 函数或方法。 “ 即时 ”窗口扮演调用应用的角色。

注释

可以在设计时将 “即时 ”窗口用于大多数项目类型。 SQL、Web 项目或脚本不支持它。

例如,若要测试类Test中命名Class1的方法:

  1. 打开 DLL 项目后,选择“调试>>”或按 Ctrl++ 打开“即时”窗口。

  2. 通过在Class1”窗口中键入以下 C# 代码并按 Enter 来实例化类型对象。 此托管代码适用于 C# 和 Visual Basic,并进行了适当的语法更改:

    Class1 obj = new Class1();
    

    在 C# 中,所有名称都必须完全限定。 当语言服务尝试计算表达式时,任何方法或变量都必须位于当前范围和上下文中。

  3. 假设Test采用一个int参数,请使用Test窗口进行评估

    ?obj.Test(10);
    

    结果打印在即时窗口中。

  4. 你可以继续调试 Test ,方法是将断点放在其中,然后再次评估函数。

    命中断点后,可以单步跟踪TestTest 执行后,调试器将回到设计模式。

混合模式调试

可以在托管代码或本机代码中为 DLL 编写调用应用。 如果本机应用调用托管 DLL 并想要调试这两者,则可以在项目属性中同时启用托管和本机调试器。 确切的过程取决于是要从 DLL 项目还是调用应用项目开始调试。 有关详细信息,请参阅 如何:在混合模式下调试

你也可以通过托管调用项目来调试原生 DLL。 有关详细信息,请参阅 如何调试托管代码和本机代码