从C#调试C++静态库

3

这个问题类似于这个未解决的问题:调试器无法在调试包含在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.

2. 对于没有本地调试的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:与第二点相同。

我拥有的代码如下:

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 封装器.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()时,在源代码中设置断点也将开始工作。 - Ben Voigt
此外,在 Visual Studio 调试器选项中,您的“仅调试我的代码”选项设置为什么? - Ben Voigt
最后,你链接的问题可能是“未回答”的,但那位程序员通过在他的Visual Studio调试器选项中启用“兼容性”模式来使他的调试体验正常工作。 - Ben Voigt
那个第一个错误信息相当奇怪,很难猜测是什么原因导致的。一定要确保链接调试版本的库。不要尝试进入本地代码,那永远不可能正常工作,只有断点能够切换活动调试引擎。您必须使用旧的调试引擎(好用的那个),工具>选项>调试>通用,“使用托管兼容性模式”必须被勾选。 - Hans Passant
1个回答

0

在我的各种尝试中,我已经启用了C#端的本机代码调试。实际上,数字1和3已经启用了它(我想我可能可以更好地解释一下),但我仍然无法在C++端获得调试器。我已经查看了您提到的教程,并且可以让它使用一个简单的C++ DLL和一个C#可执行文件工作。我的问题是将C++静态库包装在C++/CLI dll中,然后从C#调用它。 - Mauricio
@Mauricio:如果“启用本机调试”被禁用(您的情况2和4),甚至不值得尝试,因为这是应该控制此功能的设置。请关注您的第3种情况,它应该可以正常工作。 - Ben Voigt
这个答案包含了正确的调试设置。我基本上将所有设置重置为默认设置,切换了“启用本机代码调试”选项,然后它就可以工作了。不确定具体发生了什么。将调试器保持在自动状态下也可以工作。 - Mauricio

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接