Getting size of a structure

  • Thread starter Thread starter Shayne H
  • Start date Start date
S

Shayne H

How can I create a structure that gets passed to an API call that will
automatically set its size field?
I tried the following:

<StructLayout(LayoutKind.Sequential, CharSet:=CharSet.Ansi)> _
Public Structure OsVersionInfo
Shared Sub New()
Size = Marshal.SizeOf(GetType(OsVersionInfo))
End Sub
Public Shared ReadOnly Size As Integer
Public MajorVersion As Integer
Public MinorVersion As Integer
Public BuildNumber As Integer
Public PlatformId As Integer
<MarshalAs(UnmanagedType.ByValTStr, SizeConst:=128)> Public Version As
String
End Structure

However the Size field remains 0 after:

verInfo = New OsVersionInfo()

What is wrong with this technique?
 
Shayne H said:
How can I create a structure that gets passed to an API call that
will automatically set its size field?
I tried the following:

<StructLayout(LayoutKind.Sequential, CharSet:=CharSet.Ansi)> _
Public Structure OsVersionInfo
Shared Sub New()
Size = Marshal.SizeOf(GetType(OsVersionInfo))
End Sub
Public Shared ReadOnly Size As Integer
Public MajorVersion As Integer
Public MinorVersion As Integer
Public BuildNumber As Integer
Public PlatformId As Integer
<MarshalAs(UnmanagedType.ByValTStr, SizeConst:=128)> Public
Version As
String
End Structure

However the Size field remains 0 after:

verInfo = New OsVersionInfo()

What is wrong with this technique?

You must make the Size member part of each object by not declaring it
"shared". Shared members exist only once and are not part of the
OSVersionInfo object.

see also:
ms-help://MS.VSCC.2003/MS.MSDNQTR.2003FEB/cpguide/html/cpconosinfosample.htm

(see hints in signature)

You can make a class instead of a structure. Then you can write:
Public size As Integer = Marshal.SizeOf(GetType(OsVersionInfo))

There's also a managed version:
System.Environment.OSVersion


--
Armin

- Links might be split into two lines. Concatenate them using notepad.
- Links might require to add a ".nnnn" after the "2003FEB", e.g.
"2003FEB.1033" for localized versions.
- Links starting with "ms-help" are URLs for the document explorer (<F1>).
Paste them in the URL textbox and press enter. Using internal help (menu
tools -> options -> environment -> help), display the "Web" toolbar that
contains the textbox.
 
....and:

Dim verInfo As OsVersionInfo
MsgBox(OsVersionInfo.Size)
MsgBox(verInfo.Size)

This shows "144" in both Msgboxes, so I can not reproduce the problem that
the size is 0.
 
Hi Shayne,

The Size member you have declared is declared as shared. This means that it
is the same for each instance of the class, and you don't even need an
instance of the class to access it. (Note I've called the structure a class
because at a very low-level it is, and it's easier to compare it with a
class).

A shared variable is accessible without an instance of the class being
required, and can be accessed from any instance of the class.

You need to alter your 'Shared' Sub New, to just Public Sub New, and remove
the 'Shared' clause on the Size member.

--
HTH,
-- Tom Spink, Über Geek

Please respond to the newsgroup,
so all can benefit

" System.Reflection Master "

==== Converting to 2002 ====
Remove inline declarations
 
OK thanks,

Using a class solves my problem.

I understand about instances and shared members. I do have a question about
the method New() for a structure.. I got some of the code from an example
that used a Shared New() on a structure, and found that if I changed it to
non-shared VB would say that "Structures cannot declare a non-shared "Sub
New" with no parameters. What is the reason for that restriction?
 
Back
Top