将c ++指针转换为delphi

时间:2010-11-10 22:39:14

标签: delphi

实际上我正在将c ++代码转换为delphi,但我有翻译这一行的问题

PIMAGE_NT_HEADERS header = (BYTE *)lib + ((PIMAGE_DOS_HEADER)lib)->e_lfanew;

到delphi(这是我目前的结果)

var
  lib        : THandle;
  header : PImageNtHeaders;
begin
   //....
  //.....
     header := Pointer(PByte(lib) + PImageDosHeader(lib)._lfanew);   
 end;

但是编译器给了我这条消息operator not applicable to this operand type

你能帮我翻译一下吗?

6 个答案:

答案 0 :(得分:3)

header := Pointer(Integer(PByte(lib)) + PImageDosHeader(lib)._lfanew);

答案 1 :(得分:2)

你可能会回避很多这个问题。如果您正在寻找PE映像头例程,请从RTL中查找ImageHlp单元,从JCL中查找JclPeImage单元。他们有很多预先构建的代码,可以使图像和图像标题标题更容易工作。

答案 2 :(得分:0)

_lfanew成员很可能是偏移量,因此它需要是整数或DWORD而不是指针。只是猜测,因为我不使用Delhpi,但你尝试过: -

header:=指针(PByte(lib)+(DWORD)(PImageDosHeader(lib)._ lfanew));

网页搜索提出以下内容:http://www.cheesydoodle.com/?p=175

此代码基于Delphi,使用的是相同的库。您很可能会在CheesyDoodle的代码清单中找到隐藏的解决方案。

答案 3 :(得分:0)

指针运算在delphi中受到更多限制,不允许直接添加。你必须在你的指针上使用Inc函数。

示例(source):

    program PointerArithmetic;

{$APPTYPE CONSOLE}

uses
  SysUtils;

procedureWritePointer(P: PDouble);
begin
  Writeln(Format('%8p', [P]));
end;

var
  P: PDouble;

begin
  P := Pointer($50000);
  WritePointer(P);
  Inc(P);    // 00050008 = 00050000 + 1*SizeOf(Double)
  WritePointer(P);
  Inc(P, 6); // 00050038 = 00050000 + 7*Sizeof(Double)
  WritePointer(P);
  Dec(P, 4); // 00050018 = 00050000 + 3*Sizeof(Double)
  WritePointer(P);
  Readln;
end.

答案 4 :(得分:0)

我不是每天都在Delphi工作,但我怀疑这个错误是由两件事之一造成的:

  1. 未启用指针数学运算。默认情况下,Delphi不允许你进行C风格的指针操作,例如在指针中添加一个数字来获取另一个指针 - 记住Delphi是一种'安全'语言。要启用此功能,turn on pointer math using the {$POINTERMATH ON} directive。此forum posting也有更多信息。

  2. 这是我记不住的一点,因为它已经有一段时间了:你可能无法添加不同类型的指针 - 记住指针所指向的大小是不同的。在不知道_lfanew是什么的情况下,我无法向您提供更多信息。如果是这种情况,请以字节为单位获取所有内容并添加。

  3. 您也可以使用Inc函数,将代码转换为类似Delphi的代码。 Inc将按指针指向的结构大小递增类型指针,而不是一个字节。指针数学通常不是C风格的:)我认为它更好,因为它是类型感知的。

    编辑:我注意到Martin Broadhurst对你的问题的评论,指出这可能正在解析一个PE图像。如果是这样,请查看Jedi Code Library的PE图像单元。我从来没有使用它,但我知道它存在,它是C头的翻译。它也可能包括辅助函数。使用它可能意味着重写代码而不是转换代码,但最终你可能会得到更干净,更Delphi风格的代码。

答案 5 :(得分:0)

您正在处理的内容称为RVA(相对虚拟地址)。基本公式是 地址=基地+置换。当然,Address和Base是无类型指针,而Displacement是有符号整数。 Object Pascal不允许指针算术,因此需要进行类型转换。 所以:

var 
  Address, Base: Pointer; 
  Displacement: Integer;
{ ... }
Address := Pointer(Cardinal(Base) + Displacement);
{ or, in your case }
var
  Module: HMODULE; { opaque type designates module handle and equals to load address }
  NTHeaders: PImageNtHeaders;
begin
  NTHeaders := Pointer(Cardinal(Module) + PImageDosHeader(Module)^._lfanew);
  if NTHeaders^.Signature = ......