busarider29
busarider29

Reputation: 305

Is there a way to iterate through a Structure's properties?

I have a Data Structure that has a 29 boolean data types in it. Is there a way to iterate through the Struct's properties in a For loop without exlicitly stating each property name in normal property syntax.

This is what I started with but this won't work.

Public Structure ST_PLCStruct_Bools
    Public testTypeNS As Boolean                '1 byte
    Public testTypeOR As Boolean                '1 byte
    Public torqueTypeBreak As Boolean           '1 byte
    Public torqueTypeFix As Boolean             '1 byte
    Public sheaveHigh As Boolean                '1 byte
    Public sheaveLow As Boolean                 '1 byte
    Public directionCW As Boolean               '1 byte
    Public directionCCW As Boolean              '1 byte
    Public cycleStart As Boolean                '1 byte
    Public cycleStarted As Boolean              '1 byte
    Public cycleStop As Boolean                 '1 byte
    Public cycleStopped As Boolean              '1 byte
    Public pneuActuateAuto As Boolean           '1 byte
    Public pneuActuateMan As Boolean            '1 byte
End Structure

Private plcData_Bools As ST_PLCStruct_Bools

For i = 0 To 28
    plcData_Bools(i) = binaryReader.ReadBoolean
Next

Thanks.

Upvotes: 0

Views: 310

Answers (2)

Slai
Slai

Reputation: 22876

In 32 bit mode Boolean is aligned to 4 bytes

Imports System.Runtime.InteropServices

Public Structure Bools
    Public b1, b2, b3, b4, b5 As Boolean
End Structure

Sub Main()
    Dim bools = New Bools With {.b2 = True, .b4 = True}  ' {False, True, False, True, False}
    Dim size = Marshal.SizeOf(bools) ' 20
    Dim intArray%(size \ 4 - 1) 'As Integer  ' { 0, 0, 0, 0, 0 }

    Dim Ptr = Marshal.AllocHGlobal(size)
    Marshal.StructureToPtr(bools, Ptr, False)
    Marshal.Copy(Ptr, intArray, 0, size \ 4)  ' { 0, 1, 0, 1, 0 }
    Marshal.FreeHGlobal(Ptr)
End Sub

Source http://www.codeproject.com/Articles/8967/Marshaling-Structures

Upvotes: 0

Mark
Mark

Reputation: 8160

Using reflection, you can use FieldInfo.SetValue to set the values without coding the name of each field. Using a structure vs. a class complicates things a little due to boxing of value types:

Private plcData_Bools As ST_PLCStruct_Bools

Dim boxed As ValueType = plcData_Bools
For Each f In GetType(ST_PLCStruct_Bools).GetFields()
    f.SetValue(boxed, binaryReader.ReadBoolean())
Next
plcData_Bools = DirectCast(boxed, ST_PLCStruct_Bools)

Upvotes: 1

Related Questions