G
Guest
Hi there !!!
I browsed around the Internet in search for a solution of a little difficult
problem i have in VB.NET....
However, i cannot find a suitable anwser anywhere, so i thought i'll give it
a try here...
Okay, here's the deal:
I am trying to read from unmanaged memory with a class type struct, this
works fine as i can read the data from the unmanaged memory. The trouble
starts when i try to fill an array of structs within a struct, all the array
members get filled with the last read values from the unmanaged memory:
The structs i build for managing the unmanaged memory;
<code>
Imports System.Runtime.InteropServices
'Beckhoff TwinCat Struct
'TYPE ST_TeleMeBool :
'STRUCT
' ID:STRING;
' Value:BOOL;
' Qualify:STRING;
' TypeB:STRING;
'END_STRUCT
'END_TYPE
<StructLayout(LayoutKind.Sequential, pack:=1)> _
Public Class ST_TeleMeBool
'-- enum unmanagedtype ByValStr = a fixed size string of 80 chars
<MarshalAs(UnmanagedType.ByValTStr, SizeConst:=80)> _
Public ID As String = ""
<MarshalAs(UnmanagedType.I1)> _
Public Value As Boolean
<MarshalAs(UnmanagedType.ByValTStr, SizeConst:=80)> _
Public Qualify As String = ""
<MarshalAs(UnmanagedType.ByValTStr, SizeConst:=80)> _
Public TypeB As String = ""
End Class
'Beckhoff TwinCat Struct
'TYPE ST_TelemeReal :
'STRUCT
' ID:STRING;
' Value:REAL;
' Qualify:STRING;
' TypeB:STRING;
'END_STRUCT
'END_TYPE
<StructLayout(LayoutKind.Sequential, pack:=1)> _
Public Class ST_TeleMeReal
<MarshalAs(UnmanagedType.ByValTStr, SizeConst:=80)> _
Public ID As String = ""
'-- enum unmanagedtype r4 = a 4 byte Real (aka Single / system.float)
<MarshalAs(UnmanagedType.R4)> _
Public Value As Single
<MarshalAs(UnmanagedType.ByValTStr, SizeConst:=80)> _
Public Qualify As String = ""
<MarshalAs(UnmanagedType.ByValTStr, SizeConst:=80)> _
Public TypeB As String = ""
End Class
'Beckhoff TwinCat Struct
'TYPE ST_TelemeOut :
'STRUCT
' CountBool:INT;
' CountReal:INT;
' bArray: ARRAY[0..999] OF ST_TelemeBool;
' rArray: ARRAY[0..999] OF ST_TelemeReal;
'END_STRUCT
'END_TYPE
<StructLayout(LayoutKind.Sequential, pack:=1)> _
Public Class ST_TelemeOut
'-- enum unmanagedtype I2 = a 2 byte signed integer (aka short /
system.int16)
<MarshalAs(UnmanagedType.I2)> _
Public CountBool As Integer
<MarshalAs(UnmanagedType.I2)> _
Public CountReal As Integer
'-- enum unmanagedtype ByValArray = an array of which the maximum
elementsize MUST be specified (sizeconst)
<MarshalAs(UnmanagedType.ByValArray, SizeConst:=999)> _
Public bArray(1000) As ST_TeleMeBool
<MarshalAs(UnmanagedType.ByValArray, SizeConst:=999)> _
Public rArray(1000) As ST_TeleMeReal
End Class
</code>
Now the code to read the unmanaged code and fill my struct:
<code>
Public stTelemeOut As ST_TelemeOut = New ST_TelemeOut '--
declares a VB side St_TelemeOut struct to fill from PLC TelemeOut struct
Public stTelemeBool As ST_TeleMeBool = New ST_TeleMeBool '-- vb
sided instance of a single .bArray() struct element within St_TelemeOut, may
be useful
Public stTelemeReal As ST_TeleMeReal = New ST_TeleMeReal
For i = 0 To .CountBool - 1
stTelemeBool.ID = ADSClient.ReadAny(hbID(i),
GetType(String), New Integer() {80}) '--
WATCH SYNTAX TO ASK STRINGS!!!!
stTelemeBool.Value = ADSClient.ReadAny(hbValue(i),
GetType(Boolean))
stTelemeBool.Qualify = ADSClient.ReadAny(hbQualify(i),
GetType(String), New Integer() {80})
stTelemeBool.TypeB = ADSClient.ReadAny(hbTypeB(i),
GetType(String), New Integer() {80})
.bArray(i) = stTelemeBool
Next i
For i = 0 To .CountReal - 1
stTelemeReal.ID = ADSClient.ReadAny(hrID(i),
GetType(String), New Integer() {80})
stTelemeReal.Value = ADSClient.ReadAny(hrValue(i),
GetType(Single))
stTelemeReal.Qualify = ADSClient.ReadAny(hrQualify(i),
GetType(String), New Integer() {80})
stTelemeReal.TypeB = ADSClient.ReadAny(hrTypeB(i),
GetType(String), New Integer() {80})
.rArray(i) = stTelemeReal
Next i
</code>
The problem i encounter resides in the statement:
bArray(i) = stTelemeBool
and (equally so):
rArray(i) = stTelemeReal
ALL the array members get filled with the last read data values from the
unmanaged memory, this instead of filling each array member with the
corresponding unamanaged memory data.
I am at a loss... can anybody help me out??
I browsed around the Internet in search for a solution of a little difficult
problem i have in VB.NET....
However, i cannot find a suitable anwser anywhere, so i thought i'll give it
a try here...
Okay, here's the deal:
I am trying to read from unmanaged memory with a class type struct, this
works fine as i can read the data from the unmanaged memory. The trouble
starts when i try to fill an array of structs within a struct, all the array
members get filled with the last read values from the unmanaged memory:
The structs i build for managing the unmanaged memory;
<code>
Imports System.Runtime.InteropServices
'Beckhoff TwinCat Struct
'TYPE ST_TeleMeBool :
'STRUCT
' ID:STRING;
' Value:BOOL;
' Qualify:STRING;
' TypeB:STRING;
'END_STRUCT
'END_TYPE
<StructLayout(LayoutKind.Sequential, pack:=1)> _
Public Class ST_TeleMeBool
'-- enum unmanagedtype ByValStr = a fixed size string of 80 chars
<MarshalAs(UnmanagedType.ByValTStr, SizeConst:=80)> _
Public ID As String = ""
<MarshalAs(UnmanagedType.I1)> _
Public Value As Boolean
<MarshalAs(UnmanagedType.ByValTStr, SizeConst:=80)> _
Public Qualify As String = ""
<MarshalAs(UnmanagedType.ByValTStr, SizeConst:=80)> _
Public TypeB As String = ""
End Class
'Beckhoff TwinCat Struct
'TYPE ST_TelemeReal :
'STRUCT
' ID:STRING;
' Value:REAL;
' Qualify:STRING;
' TypeB:STRING;
'END_STRUCT
'END_TYPE
<StructLayout(LayoutKind.Sequential, pack:=1)> _
Public Class ST_TeleMeReal
<MarshalAs(UnmanagedType.ByValTStr, SizeConst:=80)> _
Public ID As String = ""
'-- enum unmanagedtype r4 = a 4 byte Real (aka Single / system.float)
<MarshalAs(UnmanagedType.R4)> _
Public Value As Single
<MarshalAs(UnmanagedType.ByValTStr, SizeConst:=80)> _
Public Qualify As String = ""
<MarshalAs(UnmanagedType.ByValTStr, SizeConst:=80)> _
Public TypeB As String = ""
End Class
'Beckhoff TwinCat Struct
'TYPE ST_TelemeOut :
'STRUCT
' CountBool:INT;
' CountReal:INT;
' bArray: ARRAY[0..999] OF ST_TelemeBool;
' rArray: ARRAY[0..999] OF ST_TelemeReal;
'END_STRUCT
'END_TYPE
<StructLayout(LayoutKind.Sequential, pack:=1)> _
Public Class ST_TelemeOut
'-- enum unmanagedtype I2 = a 2 byte signed integer (aka short /
system.int16)
<MarshalAs(UnmanagedType.I2)> _
Public CountBool As Integer
<MarshalAs(UnmanagedType.I2)> _
Public CountReal As Integer
'-- enum unmanagedtype ByValArray = an array of which the maximum
elementsize MUST be specified (sizeconst)
<MarshalAs(UnmanagedType.ByValArray, SizeConst:=999)> _
Public bArray(1000) As ST_TeleMeBool
<MarshalAs(UnmanagedType.ByValArray, SizeConst:=999)> _
Public rArray(1000) As ST_TeleMeReal
End Class
</code>
Now the code to read the unmanaged code and fill my struct:
<code>
Public stTelemeOut As ST_TelemeOut = New ST_TelemeOut '--
declares a VB side St_TelemeOut struct to fill from PLC TelemeOut struct
Public stTelemeBool As ST_TeleMeBool = New ST_TeleMeBool '-- vb
sided instance of a single .bArray() struct element within St_TelemeOut, may
be useful
Public stTelemeReal As ST_TeleMeReal = New ST_TeleMeReal
For i = 0 To .CountBool - 1
stTelemeBool.ID = ADSClient.ReadAny(hbID(i),
GetType(String), New Integer() {80}) '--
WATCH SYNTAX TO ASK STRINGS!!!!
stTelemeBool.Value = ADSClient.ReadAny(hbValue(i),
GetType(Boolean))
stTelemeBool.Qualify = ADSClient.ReadAny(hbQualify(i),
GetType(String), New Integer() {80})
stTelemeBool.TypeB = ADSClient.ReadAny(hbTypeB(i),
GetType(String), New Integer() {80})
.bArray(i) = stTelemeBool
Next i
For i = 0 To .CountReal - 1
stTelemeReal.ID = ADSClient.ReadAny(hrID(i),
GetType(String), New Integer() {80})
stTelemeReal.Value = ADSClient.ReadAny(hrValue(i),
GetType(Single))
stTelemeReal.Qualify = ADSClient.ReadAny(hrQualify(i),
GetType(String), New Integer() {80})
stTelemeReal.TypeB = ADSClient.ReadAny(hrTypeB(i),
GetType(String), New Integer() {80})
.rArray(i) = stTelemeReal
Next i
</code>
The problem i encounter resides in the statement:
bArray(i) = stTelemeBool
and (equally so):
rArray(i) = stTelemeReal
ALL the array members get filled with the last read data values from the
unmanaged memory, this instead of filling each array member with the
corresponding unamanaged memory data.
I am at a loss... can anybody help me out??