You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

技术问询:函数/过程能否知晓自身运行的单元/模块并访问调试信息?

关于Delphi函数/过程获取自身单元/模块信息的问题

核心结论

可以实现,但需区分有无调试信息的场景,访问调试信息的方式依赖Delphi特定API或工具链。

一、无调试信息时获取模块信息

若程序未携带调试符号,函数/过程可通过Windows API获取当前所在模块(EXE或DLL)的路径,但无法直接获取单元名称:

  • 调用GetModuleHandle配合GetModuleFileName,能拿到当前执行代码所在模块的完整路径。
  • 示例代码:
procedure GetCurrentModuleInfo;
var
  hModule: HMODULE;
  szPath: array[0..MAX_PATH] of Char;
begin
  hModule := GetModuleAddress(@GetCurrentModuleInfo);
  GetModuleFileName(hModule, szPath, MAX_PATH);
  // 将路径写入文本文件
  with TFileStream.Create('module_info.txt', fmCreate or fmShareDenyWrite) do
  try
    Write(szPath[0], StrLen(szPath) * SizeOf(Char));
  finally
    Free;
  end;
end;

二、有调试信息时获取单元/源码关联信息

当EXE/DCU包含调试信息(编译时勾选"Include remote debug symbols"或生成MAP文件),可通过以下方式访问:

  • 利用Delphi调试API:使用TDebugInfoReader类(Delphi XE及以上版本提供),读取程序调试符号,解析当前函数对应的单元名称、源码路径等信息。
  • 解析MAP文件:编译时生成MAP文件,函数内部读取该文件,通过当前指令地址匹配对应函数、单元信息。
  • 示例思路(基于调试API):
uses
  System.SysUtils, System.Classes, Winapi.Windows, DebugInfoReader;

procedure GetCurrentUnitInfo;
var
  DebugReader: TDebugInfoReader;
  Address: Pointer;
  SymInfo: TSymbolInfo;
  FileStream: TFileStream;
begin
  Address := @GetCurrentUnitInfo;
  DebugReader := TDebugInfoReader.Create(GetModuleHandle(nil));
  try
    if DebugReader.GetSymbolInfo(Address, SymInfo) then
    begin
      // SymInfo.UnitName 即为所在单元名称
      // 将信息写入文件
      FileStream := TFileStream.Create('unit_info.txt', fmCreate or fmShareDenyWrite);
      try
        FileStream.WriteBuffer(PChar(SymInfo.UnitName)^, Length(SymInfo.UnitName) * SizeOf(Char));
      finally
        FileStream.Free;
      end;
    end;
  finally
    DebugReader.Free;
  end;
end;

注意事项

  • 调试信息仅在编译时开启相关选项后才会包含在EXE/DCU中,发布版通常会移除这些信息,此时无法获取单元等源码关联信息。
  • 直接访问调试信息的操作性能较低,不建议在高频执行的代码中使用。

内容的提问来源于stack exchange,提问作者Error - CPU Not Foud

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.18 09:42:05