调试通过 LoadLibrary() 加载到 Excel 中的 C++ DLL

Posted

技术标签:

【中文标题】调试通过 LoadLibrary() 加载到 Excel 中的 C++ DLL【英文标题】:Debugging a C++ DLL loaded into Excel via LoadLibrary() 【发布时间】:2018-04-18 14:20:59 【问题描述】:

我正在编写一个基于 C++ 的 DLL,它可以导出一些函数,比如说一个简单的例子

__declspec(dllexport) int __stdcall Test()

  return 123;

然后,我通过 VBA 将此 DLL 加载到正在运行的 Excel 进程中,并调用其测试函数:

Private Declare PtrSafe Function LoadLibrary Lib "kernel32" Alias "LoadLibraryA" (ByVal lpLibFileName As String) As LongPtr
Private Declare Function Test Lib "MyLibrary.dll" () As Long

Sub executeTest()
  LoadLibrary "Path\To\MyLibrary.dll"
  Dim result As Long: result = Test()
End Sub

这很好用。但我似乎无法调试其中的 C++ 部分。

我尝试启动 Excel,并在执行任何代码之前(即在 DLL 加载到 Excel 之前),将 Visual Studio 附加到正在运行的 Excel 进程。 当我设置一个断点时,它是“白色的”——也就是“这个断点当前不会被命中。没有为此文档加载任何符号”。有道理,因为我的 DLL 还没有加载到 Excel 中。

然后,我执行 VBA 代码,该代码将加载 DLL 并调用 Test 函数。但是调试器的状态没有改变,断点保持在这个状态;它似乎从未意识到该库已加载/能够调试它。

我在那里做错了吗?在这种情况下,有没有办法调试对我的 DLL 的调用?

谢谢!

【问题讨论】:

在 VBE 中添加对 DLL 的实际引用(通过工具/引用)是否有效? 通过工具/参考添加参考时似乎是同样的问题 我不熟悉 C++,但是库有 COM 注册吗?入口点将具有特定的 GUID,您应该能够在 HKCR/CLSID/GUID 下的注册表中找到它 - 该键将具有 InprocServer32 子键,CodeBase 路径指向 DLL 位置 - 它是否存在并指向到构建路径? 确实是一个ATL COM项目;我仍然对 COM 注册感到有点不知所措——由于缺乏管理员权限(实际上没有一个 GUID 在 HKCR/CLSID 下),它无法在机器级别上注册。在任何其他注册表树中的用户级注册方面是否有类似的东西? 我不是 100% 确定,但是对于我自己的项目(VBE 的 COM 插件,用 C# 编写),我必须以管理员身份运行 VS 才能获得构建正确注册。如果您在打开 VBE 时保留对 DLL 的早期绑定引用,您仍然可以成功构建 DLL 吗?如果是这样,您不知何故没有从构建位置加载 DLL - VS 在使用时不应该覆盖 DLL。 【参考方案1】:

您可以尝试添加 __debugbreak 指令。如果 dll 是在调试中构建的,它应该会打开 Windows Just in Time 调试器。

__declspec(dllexport) int __stdcall Test()

  __debugbreak(); 
  return 123;

见https://msdn.microsoft.com/en-us//library/f408b4et.aspx

【讨论】:

以上是关于调试通过 LoadLibrary() 加载到 Excel 中的 C++ DLL的主要内容,如果未能解决你的问题,请参考以下文章

vc++ loadlibrary dll路径问题

在 Visual Studio 中构建时,LoadLibrary 无法加载错误代码 126 的 dll

《驱动调试 - 加载内核模块Unknown symbol错误分析》

动态载入DLL所需要的三个函数详解(LoadLibrary,GetProcAddress,FreeLibrary)

动态载入DLL所需要的三个函数详解(LoadLibrary,GetProcAddress,FreeLibrary)

LoadLibrary加载动态库失败