5

How should this line of code be writed to allow it to compile

MoveMemory(poleFileDescriptorW
         , (oleDataPointer + SizeOf(oleFileDescriptorW) *Index + 4)^
         , SizeOf(oleFileDescriptorW));

Particularly this part

(oleDataPointer + SizeOf(oleFileDescriptorW)*Index + 4)^

I am just want to shift the pointer by SizeOf(oleFileDescriptorW)*Index + 4 bytes

Variables are defined as:

pOLEFileDescriptorW : ^FILEDESCRIPTORW;
oleDataPointer : Pointer;
1
  • What are the types of the variables you use? Commented Nov 29, 2010 at 12:53

4 Answers 4

8

Cast to an integer type, do the math and cast back.

I usually used Cardinal but I think that doesn't work with a 64 bit compiler.

Pointer(NativeInt(oleDataPointer) + SizeOf(oleFileDescriptorW)*Index + 4)

Sign up to request clarification or add additional context in comments.

11 Comments

There is still no 64 bit version of Delphi? Still I'd like my code to work with future 64 bit delphi compilers(or 64bit freepascal)
@CodeInChaos: You can use the NativeUInt type.
You can use a PByte (or a PAnsiChar) and do pointer arithmetic directly that way
Delphi > 2009 eventually allows pointer arithmetics, just set $POINTERMATH ON.
AFAIK NativeInt was introduced in D2007 but the declaration there is wrong (64 bit). It should have been fixed in D2009 (I skipped it so I can't check).
|
7

If you're using DELPHI >= 2009, set $POINTERMATH to ON and you can use pointer arithmetic directly

Comments

2

MoveMemory and the identical CopyMemory functions accept pointers, not variables, as the Delphi RTL function Move requires (and this is the only difference between MoveMemory and Move).

So you shouldn't dereference the pointer. Just do

MoveMemory(poleFileDescriptorW,
           (oleDataPointer + SizeOf(oleFileDescriptorW)*Index + 4),
           SizeOf(oleFileDescriptorW));

where each argument is a pointer/cardinal. Depending on your actual data types, you might need to do some trivial casting. For instance, you might need to do PSomeType(cardinal(myPointer) + cardinal(myPointer2)).

Anyhow, if you would sometime need to dereference a pointer, you need to specify its type.

(oleDataPointer + SizeOf(oleFileDescriptorW)*Index + 4)^

couldn't possibly work (why?). Do

PMyType(cardinal(oleDataPointer) + SizeOf(oleFileDescriptorW)*Index + 4)^

Comments

1

Typecast to Integer.

 Pointer(Integer(oleDataPointer) + SizeOf(oleFileDescriptionW) * Index + 4)

And Andreas was right that you should use pointers directly. See if that works.

God bless

5 Comments

You should cast to cardinal, not integer (why?)! Also, MoveMemory/CopyMemory requires pointers, not variables, so you shouldn't dereference (as in the Move case).
I'd prefer an unsigned integer type, but that's mostly a stylistic issue. But your code can fail if integer overflow checks are on(they're off by default)
@andreas Why not Integer? Does Delphi do a conversion and looses data on overflow?
@codeinchaos Oh I see. Thanks for the explanation, didn't remember about the possibility of Delphi checking for integer overflow.
It doesn't matter much in practice since doing pointer-as-integer/cardinal and int overflow checking don't work well in practice anyways. So you should disable these checks in these code parts.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.