我在 Windows 上有一个 RAD Studio C++ 项目,它使用了几个使用 MS Visual Studio 构建的 DLL。调试的一大障碍是调试器不显示 DLL 中的符号。 Visual Studio 以 PDB 格式创建调试符号,而 RAD Studio 似乎生成 DWARF 符号。这两个项目共享一个共同的构建目录。
我听说最近为现代 C++ 编译器添加了 PDB 支持。这能解决我的问题吗?我能否以某种方式告诉调试器使用我的 PDB,这些 PDB 无论如何都位于构建目录中?
虽然我没有解释为什么它有效以及为什么它以前不起作用,但我可以在这里提供一个有效的最小示例。
最小示例:
文件:main.cpp(RAD Studio)
#include <iostream>
#include <tchar.h>
extern "C" __declspec(dllimport) void foo();
#pragma link "foo.dll.a"
int _tmain(int argc, _TCHAR* argv[])
{
std::cout << "entered _tmain()\n";
foo();
std::cout << "exiting _tmain()\n";
}
文件: foo_dll.cpp(Visual Studio 和 CMake)
#include <iostream>
extern "C" __declspec(dllexport) void foo()
{
std::cout << "in foo()\n";
}
文件: CMakeLists.txt(用于构建 dll)
cmake_minimum_required(VERSION 3.28)
project(foo)
add_library(foo SHARED)
target_sources(foo PRIVATE foo_dll.cpp)
add_custom_command(TARGET foo POST_BUILD
COMMAND mkexp $<TARGET_FILE:foo>.a $<TARGET_FILE:foo>
)
在 Borland 中编译 main.cpp 并使用以下命令执行 cmake 后:
cmake -G "Visual Studio 15 2017" -B build -A x64
cmake --build build
我现在可以在函数内部设置断点foo()
,调试器将在其上停止。一个小问题是不支持按 F7(步入)单步进入
foo()
:调试器不会在函数进入时停止,而仅在程序退出时停止。