调试包含在 C++/CLI DLL 中的静态库时,调试器不会进入本机代码

Posted

技术标签:

【中文标题】调试包含在 C++/CLI DLL 中的静态库时,调试器不会进入本机代码【英文标题】:Debugger does not step into native code when debugging a static lib wrapped in a C++/CLI DLL 【发布时间】:2014-05-04 20:47:31 【问题描述】:

在 C# 应用程序中,我引用了一个本地 C 静态库,我将其包装在 C++/CLI DLL 中。我选择了静态库而不是 DLL,因为我有其他与向用户发布应用程序的过程相关的限制。在这个论坛上提供的众多主题中,我找到了以下实现。

主要:


  MyCLRDLL test = new MyCLRDLL();
  if(test.go()) Console.WriteLine("Hello, wrld");

在 DLL 项目中,文件 MyCLRDLL.hpp

#include "MyNativeLib.h"
#pragma comment(lib, "MyNativeLib.lib")
namespace InteropTest 
public ref class MyCLRDLL

  CMyNativeLib* mInt ;
  public:
    MyCLRDLL()   mInt = CMyNativeLib_New() ; ;
    ~MyCLRDLL()  CMyNativeLib_Delete(mInt) ; ;
    bool go()  return mInt->areYouThere()  ; ;
;

而在原生项目中,MyNativeLib.h

namespace InteropTest

class __declspec(dllexport) CMyNativeLib

public:
  CMyNativeLib() ;
    ~CMyNativeLib();
  bool areYouThere() ;
 ;
extern "C" __declspec(dllexport) CMyNativeLib* CMyNativeLib_New();
extern "C" __declspec(dllexport) void CMyNativeLib_Delete(CMyNativeLib* pLib);

MyNativeLib.cpp

#include "MyNativeLib.h"
namespace InteropTest 
extern "C" __declspec(dllexport) CMyNativeLib* CMyNativeLib_New()return new CMyNativeLib() ;
extern "C" __declspec(dllexport) void CMyNativeLib_Delete(CMyNativeLib* pLib)delete pLib;
bool CMyNativeLib::areYouThere()  return true ; 

调试器没有进入 mInt->areYouThere() 函数。为什么呢?本机部分的断点也不会被捕获。

已为 MyCLRDLL 加载符号,“启用非托管代码调试”在 C# 项目上处于活动状态,“调试/调试器类型”设置为两个 C 项目的混合,并且在常规选项中,大多数相关内容似乎已选中。

这是否意味着 MyCLRDLL.pdb 文件不包含来自 lib 代码的调试信息?如何检查?

(可能与未回答的Debugging an unmanaged C++ static lib included in a CLR .dll 相同的问题)

【问题讨论】:

这是设计使然,您不能单步从托管代码进入非托管代码。您必须在本机代码上设置断点。当然不要忘记启用非托管代码调试。 好的,但是当我在本机代码(示例中的@areYouThere 函数)上设置断点时,即使启用了非托管代码调试,它也不会停止。你试过这个具体的例子吗? 实际上你至少可以在VS2013中从托管exe(C#)进入非托管代码dll(C++),所以我想知道静态库是prb。 终于切换到VS2013了。我可以知道调试混合模式,打开选项>调试>常规>兼容模式。 【参考方案1】:

我尝试了与您相同的设置。 C# exe 项目,引用了具有 CLR 支持的 .dll 项目,该项目引用了带有纯 Native C++ 代码的 .lib。

首先,在可执行项目属性中,您必须在“调试”选项卡中启用“在本机代码中调试”。 接下来,您将无法在附加调试器的情况下运行,因为它不会为 CLR 的本机部分加载符号。我成功地在没有附加调试器的情况下运行,然后将 CLR 项目设置为启动项目。之后,您必须使用 CTRL+ALT+P 附加到进程,并在“附加到:”中使用本机代码。 这对我有用。

【讨论】:

以上是关于调试包含在 C++/CLI DLL 中的静态库时,调试器不会进入本机代码的主要内容,如果未能解决你的问题,请参考以下文章

在调试期间进入 c++/CLI 包装器 dll 和 c# dll,同时在 firebreath 上制作插件

vc下DLL项目设置dll和lib库输出路径以及使用lib/dll库时的包含路径

我们可以静态链接动态 C 库吗?

如何防止静态库中的所有符号加载以及为什么在链接静态库时导出相同.o文件中的其他符号进行测试

使用多线程调试 DLL (/MDd) C 运行时库构建静态 Opencv 库

在 Visual Studio 2013 中调试不同解决方案中的多个项目