SizeOf Broken for Arrays in Objects

BlitzMax Forums/BlitzMax Programming/SizeOf Broken for Arrays in Objects

Gabriel(Posted 2005) [#1]
Type OSVersionInfoEx

	Field dwOSVersionInfoSize: Long
	Field dwMajorVersion:Long
	Field dwMinorVersion:Long
	Field dwBuildNumber:Long
	Field dwPlatformId:Long
	Field szCSDVersion:Byte[128]
	Field wServicePackMajor: Int
	Field wServicePackMinor: Int
	Field wSuiteMask: Int
	Field wProductType: Byte
	Field wReserved: Byte
	
End Type


Global VersionInfo:OSVersionInfoEx=New OSVersionInfoEx
Print SizeOf(VersionInfo)


It doesn't seem to be counting the 128 bytes in the array. And it's not because the array isn't automatically initiated because it still returns the same value if you add the extra VersionInfo.szCSDVersion=New Byte[128] before calling SizeOf. SizeOf works fine on arrays on their own, just not in objects.


Michael Reitzenstein(Posted 2005) [#2]
What's happening here is that in BlitzMax, szCSDVersion is a pointer to a byte array (size 4 bytes), rather than an inline byte array.

Field szCSDVersion:Byte[128]

Is shorthand for:

Field szCSDVersion:Byte[] = New Byte[ 128 ]


Gabriel(Posted 2005) [#3]
That makes sense, even if it's a huge pain in the butt. It really should be noted in the documentation for SizeOf, since the command is supposed to report the size of objects and it really isn't if the object isn't even all stored in one piece.

So there is, in fact, no way ( short of defining a type with 128 fields ) to retrieve the information returned by OSVersionInfoEx() and others like it which fill a C struct, into a type, because types are not stored in one chunk?


Michael Reitzenstein(Posted 2005) [#4]
No, which is a pain. If we had reflection you might be able to write something to automagically bind stuff, but now I think you'll just have to pass a chunk of memory then copy it into your type.


Chris C(Posted 2005) [#5]
Field szCSDVersion:Byte
field dummy1:byte
...
field dummy127:byte

:D

seriously tho some way of having a static lump of memory in a type would be handy...


skidracer(Posted 2005) [#6]
Also when converting from win32 to BlitzMax,

DWORD->int
WORD->short

this version seems to be working (note 64 bit longs will be aligned to 64 bit boundaries so need int on each end of szCSDVersion so alignment is correct):
Strict

Type OSVersionInfoEx

	Field dwOSVersionInfoSize: Int
	Field dwMajorVersion:Int
	Field dwMinorVersion:Int
	Field dwBuildNumber:Int
	Field dwPlatformId:Int

	Field szCSDVersion:Int
	Field pad0:Long
	Field pad1:Long
	Field pad2:Long
	Field pad3:Long
	Field pad4:Long
	Field pad5:Long
	Field pad6:Long
	Field pad7:Long
	Field pad8:Long
	Field pad9:Long
	Field pad10:Long
	Field pad11:Long
	Field pad12:Long
	Field pad13:Long
	Field pad14:Long
	Field pad15:Int
	
	Field wServicePackMajor: Short
	Field wServicePackMinor: Short
	Field wSuiteMask: Short
	Field wProductType: Byte
	Field wReserved: Byte
	
End Type

Extern "win32"
Function GetVersionExA(infoex:Byte Ptr)
End Extern

Global VersionInfo:OSVersionInfoEx=New OSVersionInfoEx
VersionInfo.dwOSVersionInfoSize=SizeOf(VersionInfo)
If GetVersionExA(VersionInfo)
	Print "Windows version "+VersionInfo.dwMajorVersion+"."+VersionInfo.dwMinorVersion
	Print "Build Number "+VersionInfo.dwBuildNumber
	Print "Platform ID "+VersionInfo.dwPlatformId
	Print "CSDVerion "+String.FromCString(Varptr VersionInfo.szCSDVersion)
EndIf