Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations TouchToneTommy on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

Basic Delphi Syntax - 'C' conversion

Status
Not open for further replies.

JBloggs2079

Technical User
Jul 5, 2006
3
GB
Hi there,

I'm trying to convert a piece of Delphi to C, and am not sure what the following code is doing, if anyone here could help me out that'd be great.

Declared at the top is

function GetBigPointer(lp : pointer;
Offset : Longint) : Pointer;
begin
\{$IFDEF WIN32\}
GetBigPointer := @PByteArray(lp)^ ;Offset];
\{$ELSE\}
Offset := Offset + TPtrRec(lp).Lo;
GetBigPointer := Ptr(TPtrRec(lp).Hi + TPtrRec(Offset).Hi *
SelectorInc,
TPtrRec(Offset).Lo);
\{$ENDIF\}

hPixelBuffer : THandle; \{Handle to the pixel buffer\}
lpPixelBuffer : pointer; \{pointer to the pixel buffer\}

Further down there is

hPixelBuffer := GlobalAlloc(GHND, BitmapSize);
lpPixelBuffer := GlobalLock(hPixelBuffer);

FillChar(lpPixelBuffer^, BitmapSize, #0);

for i := 0 to 255 do
for j := 0 to 255 do
Byte(GetBigPointer(lpPixelBuffer, i + (j * 256))^) := j;

--------------

Now I'm assuming this should convert as

HANDLE hPixelBuffer;
HANDLE* lpPixelBuffer;
lpPixelBuffer = &hPixelBuffer

That is that hPixelBuffer is of type HANDLE from the Win32 api, and lpPixelBuffer is a pointer that points to it.

The FillChars I have as

hPixelBuffer = (HANDLE)malloc(bitmapSize);
memset (hPixelBuffer, 0, sizeof (bitmapSize));

I however have no idea whats going on with that function.

Its passing a pointer to a HANDLE plus a number. Say we go into the
\{$IFDEF WIN32\}
part
GetBigPointer := @PByteArray(lp)^ ;Offset];

This seems to return a @PByteArray which takes the pointer as a parameter, and using [Offset] as an array index. But an index to what array ? Is an array being created here or what? Then whatever is being returned here is going into
Byte(... return value ...) = j

If someone could explain this syntax, I'd much appreciate it.

Thanks :)
 
Uuuu... that is old code, man; lemme try.

1)
The {$ELSE} in GetBigPointer is Win16 code, forget it.

2)
The statements:

hPixelBuffer := GlobalAlloc(GHND, BitmapSize);
lpPixelBuffer := GlobalLock(hPixelBuffer);

are legacy code too. GlobalAlloc returns a handle and GlobalLock "locks" the memory chunk and returns a pointer. It was from the age when memory was moveable.

Modern memory management returns pointers, not handles, so the up to date way to do it is:

Getmem(lpPixelBuffer, bitmapSize) // PASCAL
lpPixelBuffer = malloc(bitmapSize); // C

where lpPixelBuffer is a POINTER, not a HANDLE.

3)
FillChar(lpPixelBuffer^, BitmapSize, #0);

is the same as

memset (lpPixelBuffer, 0, sizeof (bitmapSize));

4)
In a whole, GetBigPointer is pointer aritmethic, basically for Win16, where the memory was segmented.

The only thing the code is doing is adding an offset to a base pointer (lpPixelBuffer).

All the obfuscation is due the compatibility with Win16 memory management.

---------
Need to attend some urgent things. Feel free to ask anything else.
---------

buho (A).




 
Thanks for the info.

If lpPixelBuffer is a pointer, what type is it pointing to? Or does this not need declared initially in Delphi ?

The calling code for the function is

for i := 0 to 255 do
for j := 0 to 255 do
Byte(GetBigPointer(lpPixelBuffer, i + (j * 256))^) := j;

What exactly is going on here? If the function is adding an offset to the lpPixelBuffer pointer, then the pointer must be pointing to an array? But this isn't defined at the start...
What is being passed back into this calling Byte(...), which is obviously being called 256*256 times...

Thanks again :)
 
In the original code, the pointer is an untyped pointer (PASCAL pointer = C void pointer).

The memory is an array of bytes. An untyped pointer and a byte array pointer is exactly the same thing. The difference is *the sintax* needed to work with them.

char *cp[100];
...
*cp[n] = x;

is the same as

void *vp;
...
*(vp + n) = x;

What the loops are doing is:

for(i = 0; i <= 255; i++)
for(j = 0; j <= 255; j++)
cp[i + j * 256] = j;

or

for(i = 0; i <= 255; i++)
for(j = 0; j <= 255; j++)
*(vp + i + j * 256) = j;

(Check the sintaxis carefully, I don't like C and I use it as little as I can)

The programmer is looking at the unidimensional vector as a 2x2 matrix and writing j in every file:

Code:
     0    1    2  [COLOR=red]--- [b]i[/b] ---[/color]  255
    .--------------------------
0   |0,   0,   0,   0,   ..., 0
1   |1,   1,   1,   1,   ..., 1
2   |2,   2,   2,   2,   ..., 2
    |
[COLOR=red]|[/color]   |
[COLOR=red]|[/color]   |
[COLOR=red][b]j[/b][/color]   |
[COLOR=red]|[/color]   |
[COLOR=red]|[/color]   |
    |
255 |255, 255, 255, 255, ..., 255

Why the programmer is doing this I can't say. Either he is showing a square of 256x256 pixels with a vertical transition of colors or he is doing it for debugging purposes (my bet).

IMO, the programmer decided to use an untyped pointer due to the segmented model limitations. In today flat address space, the best data structure is the byte array (or may be the bidimensional matrix -can´t say knowing only this code snippet).

buho (A).


 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top