【问题标题】:Debugging C++ static lib from C#从 C# 调试 C++ 静态库
【发布时间】:2020-02-06 06:44:08
【问题描述】:

这个问题类似于这个未回答的问题:Debugger does not step into native code when debugging a static lib wrapped in a C++/CLI DLL

设置是一样的。我有一个纯 C++ 静态库,它链接到 C++/CLI DLL,然后由 C# 可执行文件使用。根据设置,我可以调试 C# 层,或者同时调试 C# 和 C++/CLI。无论我尝试什么,我都无法调试 C++ 层。我正在使用 Visual Studio 2019。

这是我尝试过的方法和结果。对于下面描述的所有场景,我在 C++/CLI 和 C++ 函数(不是 C#)上设置了断点。

  1. 带有本机调试的 C#、带有自动调试的 C++ 和 C++/CLI:调试器在 C# 中会调用 C++/CLI 函数的调用处停止,但我无法设置它们。 Visual Studio 没有关于 C++/CLI 端断点的消息(它们处于活动状态但无法命中)。在 C++ 方面,它说:
This breakpoint will not currently be hit. Breakpoints in module clr.dll are not alowed. This module contains the implementation of the underlying runtime you are trying to debug.
  1. 没有本机调试的 C#、具有混合调试的 C++ 和 C++/CLI:C++/CLI 中的断点被命中并处于活动状态。 C++ 断点要么消失,要么出现以下消息:
This breakpoint will not currently be hit. No executable code of the debugger's target code is associated with this line. Possible causes include: conditional compilation, compiler optimizations, or the target architecture of this line is not supported by the current debugger code type.
  1. 带有本机调试的 C#、带有混合调试的 C++ 和 C++/CLI:见第一点,行为是相同的。
  2. C# 不带原生调试,C++ 带原生调试,C++/CLI 带混合调试:同第 2 点。

我的代码如下:

C++ Native.hpp:

#pragma once
namespace native
{
   class Native
   {
   public:
      Native();

      bool here() const;
   };
}

C++ Native.cpp:

#include "Native.hpp"

#include <iostream>

namespace native
{
   Native::Native()
   {
      std::cout << "Created native entity!" << std::endl; // breakpoint here
   }

   bool Native::here() const
   {
      std::cout << "Native is here!" << std::endl; // breakpoint here
      return true;
   }
}

C++/CLI Wrapper.h:

#pragma once

#include "../cpp/Native.hpp"

using namespace System;

namespace clr
{
    public ref class Wrapper
    {
   public:
      Wrapper() 
      { 
         Console::WriteLine("Building wrapper for native"); // breakpoint here
         mNative = new native::Native(); 
      }
      ~Wrapper() { delete mNative; }
      bool go() 
      { 
         Console::WriteLine("In wrapper to find native..."); // breakpoint here
         return mNative->here(); 
      }

   private:
      native::Native* mNative;

    };
}

和 C#:

using System;
using clr;

namespace csharp
{
    class Program
    {
        static void Main(string[] args)
        {
            Wrapper w = new Wrapper();
            Console.WriteLine("Finding native through wrapper...");
            w.go();
            Console.WriteLine("Waiting...");
            Console.Read();
        }
    }
}

我已经尝试了所有我能想到的东西,但我无法调试 C++ 端。我非常感谢任何帮助解决这个问题。

【问题讨论】:

  • 您正在浪费大量时间测试没有希望工作的场景,因为它们告诉调试器不要查看本机 C++ 代码。使用您的配置 #3 并在您的本机 C++ 代码中添加内部函数调用 __debugbreak();。这将使调试器停在那里。您可能会从调试器那里收到关于未加载符号或未正确配置源代码路径或类似情况的投诉。一旦你解决了当你点击__debugbreak() 时阻止源代码调试的特定问题,在源代码中设置断点也将开始工作。
  • 另外,您在 Visual Studio 调试器选项中设置的“仅调试我的代码”选项是什么?
  • 最后,您链接到的问题可能“未得到解答”,但那里的程序员通过在其 Visual Studio 调试器选项中启用“兼容性”模式获得了调试经验。
  • 第一条错误消息非常不可靠,很难猜出是什么原因导致的。请确保链接该库的调试版本。不要尝试单步执行本机代码,这永远无法正常工作,只有断点才能切换活动的调试引擎。您绝对必须使用旧的调试引擎(好的),工具>选项>调试>常规,必须选中“使用托管兼容模式”。

标签: c# c++ c++-cli


【解决方案1】:

这可能就像在 Visual Studio 中未启用 Enable native code debugging 一样简单。

docs.microsoft.com 的 Tutorial: Debug C# and C++ in the same debugging session 包含成功进行 c#+c++ 调试会话的步骤。

【讨论】:

  • 在我的各种尝试中,我在 C# 端启用了本机代码调试。事实上,数字 1 和 3 已启用它(我想我可以更好地解释这一点),但我仍然无法在 C++ 端获得调试器。我看过你提到的教程,我可以让它与一个简单的 C++ DLL 和一个 C# 可执行文件一起工作。我的问题是将 C++ 静态库包装在 C++/CLI dll 中,然后从 C# 调用它。
  • @Mauricio:禁用“启用本机调试”(您的情况 2 和 4)甚至不值得尝试,因为这是应该控制此功能的设置。专注于你的案例 3,它应该有效。
  • 此答案包含要调试的正确设置。我基本上将everyrthing重置为默认设置,切换Enable native code debugging并且它起作用了。不知道到底发生了什么。将调试器留在自动工作中。
猜你喜欢
  • 2019-12-19
  • 1970-01-01
  • 1970-01-01
  • 2016-09-07
  • 2011-11-01
  • 2015-01-18
  • 2020-01-03
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多