0

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.

Chris Dunaway
  • 10,974
  • 4
  • 36
  • 48
busarider29
  • 185
  • 5
  • 18
  • You mean like a collection? – Ňɏssa Pøngjǣrdenlarp Jul 12 '16 at 19:08
  • What does your data structure code look like (we only need a sample of the properties)? It sounds like you may be wanting to use reflection to set the property values, but I can't really tell from your question. – Mark Jul 12 '16 at 19:24
  • It would be nice to use as a collection but I don't know how to do that and I'm not familiar with reflection or how that works. Thanks for the help. – busarider29 Jul 12 '16 at 20:01
  • 1
    What not learn Something New and Useful? Those are not properties BTW, they are just public fields. That whole thing is little more than a List or perhaps Dictionary – Ňɏssa Pøngjǣrdenlarp Jul 12 '16 at 20:59
  • I agree, I will look into reflection and learn how that works. – busarider29 Jul 13 '16 at 11:42
  • As a side note, those `Boolean`s seem to be stored as 4 Bytes each. Calling `Marshal.SizeOf` reports a size of 56 bytes, although I'm not sure if that is the .Net size or the size for PInvoke purposes. – Chris Dunaway Jul 13 '16 at 14:31

2 Answers2

1

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)
Community
  • 1
  • 1
Mark
  • 8,140
  • 1
  • 14
  • 29
  • I have to use a Structure for getting/setting variables to/from the PLC project. Maybe there is another way to do it via a class (?), but I'm just following what's shown in the Beckhoff Infosys online documentation. Anyway, it looks like using reflection will work. Thank you for the assistance! – busarider29 Jul 13 '16 at 11:49
0

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

Slai
  • 22,144
  • 5
  • 45
  • 53