使用本机C++、托管 C++ CLI 和 C# 解决方案在混合模式下进行调试

本文关键字:C++ 模式 混合 调试 解决方案 本机 托管 CLI | 更新日期: 2023-09-27 17:56:06

我有一个多线程项目正在处理,启动项目设置为运行我的 UI 的 c# 项目。然后是一系列基础 c++ 本机项目,这些项目通过托管 C++/CLI 项目连接到 C#。我已经在 c# 启动项目"启用非托管调试"中启用了,当我尝试调试本机代码时,我能够命中我设置的断点。但是,在我尝试再次运行它并尝试再次达到中断点后,它挂起。例如,如果我有一个循环,我尝试在每次迭代中点击它,在第二次迭代后程序挂起,我必须强制退出。我在Visual Studio 2010工作。调试开始证明以这个速度不太有用,有什么方法可以排除这个问题吗?

使用本机C++、托管 C++ CLI 和 C# 解决方案在混合模式下进行调试

当我想调试本机代码以及 C++/CLI 时,我执行以下操作:

  1. 在 C# 应用程序中,选中项目属性的"生成"选项卡中的"Allow unsafe code"和"调试"选项卡中的Enable unmanaged code debugging
  2. 对于 C++/CLI dll 项目,在属性的"调试"选项卡中,将"调试器类型"设置为"Mixed

我们在调试复杂的混合代码应用程序时也遇到了问题,并发现Visual Studio在这些情况下并不那么可靠。我的建议是:

  • 如果尝试调试一段本机代码,请尝试使用本机项目作为调试器启动应用程序。在项目设置下,"调试"选项卡将"调试器类型"设置为"混合",这有时对我们有帮助(例如,本机项目可以是 DLL,只需在项目设置中将主 Exe 设置为调试目标);

  • 使用 WinDbg,您可以更可靠地调试托管/非托管混合代码应用程序;

当我尝试从托管端单步执行非托管代码时,我遇到了同样的问题,因此,我摆脱了托管端的所有断点并执行以下操作:

1) 通过文件>

打开>文件(即我的源.cpp)打开您的非托管源文件

2)在那里设置断点

3) 启动托管代码调试("播放"按钮)

它应该直接进入您的非托管代码...至少它对我有用...

好的,这是我如何解决它,

简答:

  1. Set Configuration_Properties->Debugging->Debugger_type: Mixed (.NET Framework)对于您的两个项目

    a. 纯本机项目(非托管C++ exe 使用从托管C++ CLR dll 导出的函数)

    b. C++/CLI - CLR 项目(托管C++ DLL 从纯托管导出函数通过引用的 C# .NET dll(对 C# dll 的引用已添加到托管C++ CLR 项目的引用列表中)) - 此项目作为接口 b/w 非托管和托管代码。

  2. 为充当接口的托管 C++/CLI - CLR 项目设置 Configuration_Properties->高级>C++/CLI_Properties->Common_Language_Runtime_Support:公共语言运行时支持 (/clr) 和.NET_Target_Framework_Version:x.x.x(在托管 C# 项目目标框架中指定)。

长答案:

我试图构建一个插件DLL(C++本机dll),它应该在使用MFC/Win32 API集的普通非托管环境(C++本机)下运行。首先,我尝试使用 Win32Api UI 元素,例如窗口、线程等,它成为设计 UI 的核心,因为 VS2019 不会给我设计编辑器,除非我将项目声明为 MFC 并引入不需要的 MFC 服务。

为了使我的 UI 开发更容易,

我创建了一个C# dll(托管dLL - 标准类库.NET Core项目),它使用面向.NET框架4.7.2的"Windows Forms"。

然后我创建了另一个C++/CLI - CLR dll(托管 dLL - CLR 项目,它使用非托管C++代码但在托管环境中运行 clr.dll)。此 dll 充当一个接口,它使用 extern "C" __declspec(dllexport) 公开包装在 C 样式包装器函数中的托管 C# 代码中的函数

主/启动项目是一个纯本机C++ (exe) 非托管应用程序,它使用从内部公开 UI 元素的 C++/CLI - CLR 托管接口项目导出的功能。

除非我手动加载托管 CLR C++ dll 的.pdb,并将启动非托管C++应用程序的调试器类型强制到混合(.NET Framework),否则调试不可用