views:

287

answers:

3
var Buffer: TMemoryStream

The code:

Move((PByte(Buffer.Memory)+Buffer.Position)^, Buffer.Memory^, Buffer.Size - Buffer.Position);

Unfortunately this is not possible: Operator is not applicable to this type of operand.

So how can I get the starting point of a MemoryBuffer?

A: 

You are casting Buffer.Memory to PByte and want to add an Int64 value. That doesn't work (Delphi is very strict about what you do with pointers). Try this:

Move(Pointer(Int64(Buffer.Memory)+Buffer.Position)^, Buffer.Memory^, Buffer.Size - Buffer.Position);

This works to:

Move(PAnsiChar(Buffer.Memory)[Buffer.Position], Buffer.Memory^, Buffer.Size - Buffer.Position);

This "should" work in Delphi 2009 with pointermath on:

Move(PByte(Buffer.Memory)[Buffer.Position], Buffer.Memory^, Buffer.Size - Buffer.Position);
The_Fox
The latter example would only work if `Memory`'s type were `PByte`. Isn't it still `Pointer`?
Rob Kennedy
I added an cast to PByte, but isn't it possible to just use Pointer?
The_Fox
+4  A: 

You can only add/subtract integer from a character pointer. From Delphi help:

You can use the + and - operators to increment and decrement the offset of a character pointer. You can also use - to calculate the difference between the offsets of two character pointers. The following rules apply.

If I is an integer and P is a character pointer, then P + I adds I to the address given by P; that is, it returns a pointer to the address I characters after P. (The expression I + P is equivalent to P + I.) P - I subtracts I from the address given by P; that is, it returns a pointer to the address I characters before P. This is true for PChar pointers; for PWideChar pointers P + I adds SizeOf(WideChar) to P.

If P and Q are both character pointers, then P - Q computes the difference between the address given by P (the higher address) and the address given by Q (the lower address); that is, it returns an integer denoting the number of characters between P and Q. P + Q is not defined.

Try this:

Move((PAnsiChar(Buffer.Memory)+Buffer.Position)^, Buffer.Memory^, Buffer.Size - Buffer.Position);
Kcats
Use PAnsiChar, not PChar, lest your code suddenly get weird errors next time you upgrade Delphi.
Rob Kennedy
You are absolutely correct, I have edited my answer, thank you.
Kcats
+2  A: 

I think that original code with PByte should work in Delphi 2009, as it now has more types with pointer math enabled.

Alexander
True, but you need to add {$pointermath on} to enable that afaik.
Marco van de Voort
No, you don't.You can use pointermath to enable pointer math on new type or on block of code. Build-in PByte type already have pointer math enabled, so you don't need any additional directives.
Alexander