472,353 Members | 1,963 Online
Bytes | Software Development & Data Engineering Community
+ Post

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 472,353 software developers and data experts.

Struct trouble Visual Basic.net

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??
Nov 21 '05 #1
4 3939
Couple of questions here
when i = 0 and you check the value of hbID is it the same when i=ubound(i)
if that is the case then your hb object is not getting declared or populated
correct
if they are not the same then take a look at
since your not rediming your arrays then that could be reason.. All though
never seen that to be a problem but
redim array(ubound(.countreal))
before you start looping to fill your array

you do not show us how hb is getting filled
If the other component is filling hb.. When you get hb back make sure it is
more then array of 1

"DaHool" <Da****@discussions.microsoft.com> wrote in message
news:F0**********************************@microsof t.com...
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??

Nov 21 '05 #2
> 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 problem is that you reuse the same instance of the object every
time through the loop. Your rArray was filled with references to the
*SAME* object. You need to create a NEW object each time inside the
for loops, like this:
Public stTelemeBool As ST_TeleMeBool
Public stTelemeReal As ST_TeleMeReal

For i = 0 To .CountBool - 1 stTelemeBool = New ST_TelemeOut 'CREATE A NEW OBJECT
HERE

'Code to set stTelemeBool properties
.bArray(i) = stTelemeBool
Next i
For i = 0 To .CountReal - 1 stTelemeReal = New ST_TeleMeReal 'CREATE A NEW OBJECT
HERE

'Code to set stTelemeReal properties
.rArray(i) = stTelemeReal
Next i
</code>


Once you create the objects inside the for loops you should be ok

Nov 21 '05 #3
that is not the problem if you look at the code below he
makes stTelemeReal = the array at the end of the loop
So does not matter if he resues the stTelemeReal
over and over in his loops

"Chris Dunaway" <du******@gmail.com> wrote in message
news:11**********************@o13g2000cwo.googlegr oups.com...
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 problem is that you reuse the same instance of the object every
time through the loop. Your rArray was filled with references to the
*SAME* object. You need to create a NEW object each time inside the
for loops, like this:
Public stTelemeBool As ST_TeleMeBool
Public stTelemeReal As ST_TeleMeReal

For i = 0 To .CountBool - 1

stTelemeBool = New ST_TelemeOut 'CREATE A NEW OBJECT
HERE

'Code to set stTelemeBool properties
.bArray(i) = stTelemeBool
Next i
For i = 0 To .CountReal - 1

stTelemeReal = New ST_TeleMeReal 'CREATE A NEW OBJECT
HERE

'Code to set stTelemeReal properties
.rArray(i) = stTelemeReal
Next i
</code>


Once you create the objects inside the for loops you should be ok

Nov 21 '05 #4
It does matter, when he assigns the object reference to the array in
this line
.rArray(i) = stTelemeReal


He now has two refereneces *to the same object*. At the end of the
loop, *all* the array elements point to the same object. And since
there is only one object, they all reflect the values of the most
recent changes.

Had he defined his "structs" as Structures instead of classes it may be
different, since he would then be working with value types and not
reference types.

Chris

Nov 21 '05 #5

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

3
by: Roland Dreier | last post by:
I'm used to initializing struct fields by name using the designator syntax that is a part of ISO C99. For example: struct foo { int x; int y;...
4
by: quek | last post by:
Im having a problem passing a struct ptr. Maybe someone could help me. Heres what Visual C gives me as error: error C2664: 'adpcm_coder_u' :...
1
by: Russell Mangel | last post by:
Sorry about the Cross-Post, I posted my question in the wrong group. Hello, What is the simplest way to create a dynamic collection (during...
3
by: Sudheer Gupta | last post by:
Hi, I am having trouble using C struct in python. Hope anyone can help me out ... Say, I have my C struct as typedef struct call { struct...
11
by: nephish | last post by:
hello there, all. i have a difficult app that connects to a server to get information for our database here. this server is our access point to...
1
by: stromhau | last post by:
Hi, I have made a few classes in c++. They somehow cooperate doing some 3d stuff. Basically it is a moving camera acting as a flight, i have...
1
by: yucikala | last post by:
Hello, I'm a "expert of beginner" in C#. I have a dll - in C. And in this dll is this struct: typedef struct msg_s { /* please make duplicates...
2
by: yalbizu | last post by:
#include <iostream> #include <string> #include <fstream> #include <iomanip> using namespace std; const int NO_OF_STUDENTS=20; struct...
4
by: Lew Pitcher | last post by:
(having trouble getting my reply through - hopefully, third time is a charm) On November 11, 2008 19:53, in comp.lang.c, BIll Cunningham...
0
by: Naresh1 | last post by:
What is WebLogic Admin Training? WebLogic Admin Training is a specialized program designed to equip individuals with the skills and knowledge...
0
by: antdb | last post by:
Ⅰ. Advantage of AntDB: hyper-convergence + streaming processing engine In the overall architecture, a new "hyper-convergence" concept was...
0
by: Matthew3360 | last post by:
Hi there. I have been struggling to find out how to use a variable as my location in my header redirect function. Here is my code. ...
2
by: Matthew3360 | last post by:
Hi, I have a python app that i want to be able to get variables from a php page on my webserver. My python app is on my computer. How would I make it...
0
by: AndyPSV | last post by:
HOW CAN I CREATE AN AI with an .executable file that would suck all files in the folder and on my computerHOW CAN I CREATE AN AI with an .executable...
0
hi
by: WisdomUfot | last post by:
It's an interesting question you've got about how Gmail hides the HTTP referrer when a link in an email is clicked. While I don't have the specific...
0
by: Matthew3360 | last post by:
Hi, I have been trying to connect to a local host using php curl. But I am finding it hard to do this. I am doing the curl get request from my web...
0
Oralloy
by: Oralloy | last post by:
Hello Folks, I am trying to hook up a CPU which I designed using SystemC to I/O pins on an FPGA. My problem (spelled failure) is with the...
0
by: Carina712 | last post by:
Setting background colors for Excel documents can help to improve the visual appeal of the document and make it easier to read and understand....

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.