【问题标题】:How to determine if dll file was compiled as x64 or x86 bit using either Delphi or Lazarus如何使用 Delphi 或 Lazarus 确定 dll 文件是编译为 x64 还是 x86 位
【发布时间】:2010-05-01 01:05:45
【问题描述】:

使用 Delphi 2007+ 或 Lazarus(Win64) 我正在寻找一种方法来确定 dll 是编译为 x64 还是 x86?

【问题讨论】:

  • 我找到了以下资料,但还没来得及同化:tech-archive.net/Archive/Development/…这个链接:delphidabbler.com/articles?article=8&part=2上一篇链接文章中提到的提供Delphi源码解析文件头可以识别 16 位和 32 位,但不是 64 位。代码可以在 Delphi 2007 上按原样运行,但不能在 Delphi2010 或 Lazarus 上运行 - 至少在我没有时间或经验的情况下没有更多的修改。

标签: delphi winapi 64-bit lazarus


【解决方案1】:

您应该阅读并解析 PE 标头。

像这样:

function Isx64(const Strm: TStream): Boolean;
const
  IMAGE_FILE_MACHINE_I386     = $014c; // Intel x86
  IMAGE_FILE_MACHINE_IA64     = $0200; // Intel Itanium Processor Family (IPF)
  IMAGE_FILE_MACHINE_AMD64    = $8664; // x64 (AMD64 or EM64T)
  // You'll unlikely encounter the things below:
  IMAGE_FILE_MACHINE_R3000_BE = $160;  // MIPS big-endian
  IMAGE_FILE_MACHINE_R3000    = $162;  // MIPS little-endian, 0x160 big-endian
  IMAGE_FILE_MACHINE_R4000    = $166;  // MIPS little-endian
  IMAGE_FILE_MACHINE_R10000   = $168;  // MIPS little-endian
  IMAGE_FILE_MACHINE_ALPHA    = $184;  // Alpha_AXP }
  IMAGE_FILE_MACHINE_POWERPC  = $1F0;  // IBM PowerPC Little-Endian
var
  Header: TImageDosHeader;
  ImageNtHeaders: TImageNtHeaders;
begin
  Strm.ReadBuffer(Header, SizeOf(Header));
  if (Header.e_magic <> IMAGE_DOS_SIGNATURE) or
     (Header._lfanew = 0) then
    raise Exception.Create('Invalid executable');
  Strm.Position := Header._lfanew;

  Strm.ReadBuffer(ImageNtHeaders, SizeOf(ImageNtHeaders));
  if ImageNtHeaders.Signature <> IMAGE_NT_SIGNATURE then
    raise Exception.Create('Invalid executable');

  Result := ImageNtHeaders.FileHeader.Machine <> IMAGE_FILE_MACHINE_I386;
end;

【讨论】:

  • 感谢您的回复。不幸的是,这需要 JCL 才能工作。我还没有将 JCL 添加到我的 Delphi 2007 中,但如果它看起来是唯一的权宜之计,可能会。
  • 您的更新版本在 Delphi 2007 和 Delphi 2010 中运行良好。一个优雅的解决方案 - 谢谢。
  • 请注意,这些常量在 FPC 上以 Windows 为单位。 (至少在 2.4.0+ 不知道旧的)
【解决方案2】:

您可以使用 JCL 中的 JclPeImage。下面的应用程序展示了如何做到这一点。


program Isx64ImageTest;

{$APPTYPE CONSOLE}

uses
  SysUtils, JclWin32, JclPEImage;

var
  PEImage: TJclPeImage;
begin
  PEImage := TJclPeImage.Create;
  try
    //usage is "Isx64ImageTest filename"
    PEImage.FileName := ParamStr(1);
    //print the machine value as string
    WriteLn(Format('Machine value of image %s is %s',
      [PEImage.FileName, PEImage.HeaderValues[JclPeHeader_Machine]]));
    //check for a special machine value
    case PEImage.LoadedImage.FileHeader^.FileHeader.Machine of
      IMAGE_FILE_MACHINE_I386:  begin end;
      IMAGE_FILE_MACHINE_AMD64: begin end;
      else
      begin
      end;
    end;
  finally
    PEImage.Free;
  end;
end.

【讨论】:

  • 如果您使用 JCL - 有更简单的方法 - 通过使用 PeMapImgTarget 函数或 PEImage.Target 属性(在您的示例中)。无需自己分析标头。
  • 尚未使用 JCL,可能最终会这样做。我一直在尝试镜像我的 Delphi2007 和 Delphi2010 组件,因为我一直在计划迁移到 Delphi2010。 Delphi2010 可以使用 JCL 吗?
猜你喜欢
  • 2010-10-03
  • 1970-01-01
  • 2010-11-01
  • 2013-10-06
  • 2019-04-02
  • 2021-05-21
  • 2014-08-15
  • 1970-01-01
相关资源
最近更新 更多