Memory allocation of a long

I defined a structure with a long variable, which is located on an even boundary, but the compiler handles this as if the long is located on a 4-byte boundary. The strange thing is that the compiler shows the correct total length of the structure (as if there are no slack bytes).

You can see this for yourself.

Create an agent and populate it with the following code:

Type Wrong

ifield1 As Integer

lfield As Long

ifield2 As Integer

End Type

Declare Private Sub Poke Lib “MSVCRT” Alias “memcpy” ( Byval P As Long, D As Any, Byval N As Long)

Declare Function W32_OSLockObject Lib “nnotes.dll” Alias “OSLockObject” (Byval handle As Long) As Long

Declare Function W32_OSUnlockObject Lib “nnotes.dll” Alias “OSUnlockObject” (Byval handle As Long) As Integer

Declare Function W32_OSMemAlloc Lib “nnotes.dll” Alias “OSMemAlloc” ( Byval x As Integer, Byval y As Long, z As Long) As Integer

Declare Sub MoveMemory Lib “kernel32” Alias “RtlMoveMemory” (Destination As Any, Source As Any, Byval Length As Long)

Sub Initialize

Dim w As Wrong

Dim rc As Integer

Dim p As Long

Dim pw As Long



w.ifield1 = 255

w.lfield = 1

w.ifield2 = 16

Msgbox "Size of Wrong:  " + Cstr(Len(w))

rc = W32_OSMemAlloc(0, Len(w), pw)

p = W32_OSLockObject(pw)

Call Poke(p, w, Len(w))

Call dumpHandle(pw, Len(w))

W32_OSUnlockObject(pw)

End Sub

Sub dumpHandle(hbuffer As Long, hlen As Long)

Dim i As Long

Dim pbuffer As Long

Dim dump As String



pbuffer = W32_OSLockObject(hbuffer)

Redim buffer(1 To hlen) As Byte

MoveMemory buffer(1), Byval pbuffer, hlen

For i = 1 To hlen

	dump = dump + " " + Right$("0" + Hex(buffer(i)), 2)

Next

dump = Left$(dump, hlen * 3)

W32_OSUnlockObject(hbuffer)

Msgbox dump

End Sub

When you run this, you will notice that the size of the structure is 8 bytes, which is correct.

Its value should be FF FF 01 00 00 00 10 00, but it is:

FF 00 00 00 01 00 00 00

It shows two things:

a) the first byte is filled, but the first 2 bytes should contain FF FF.

b) there are 2 extra 00 included.

Who recognises this?

Subject: RE: Memory allocation of a long

I think FF 00 is the correct representation for the value 255 – not FF FF.

So, it looks like the DWORD is aligned on a DWORD boundary. I guess you will have to declare your Long as a pair of Integers instead.

The documentation for Len actually doesn’t cover the case where the argument is an instance of a structure, but it does say, “For typeName, Len returns the number of bytes required to hold the contents of all the member variables…” To me, this seems to be saying that if you have a Byte and a Long, you should expect to get 9, not 9 plus whatever padding was required to align the data.

Len would probably be more useful if it returned the total size of the structure, but that’s apparently not what it was designed to do.

Subject: RE: Memory allocation of a long

You are right about the FF FF not being 255.

Of course I changed the long into 2 integers to bypass the problem.

I expected the “Len” function to behave as the “sizeof” function you will see in languages like C.

Now that I think of it, this is probably why there is a macro call ODSLength in the C API.