473,321 Members | 1,748 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

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

How to use legacy structures

I have a legacy structure that appears on a communications line that has 16 bit, 8 bit, 2 bit and 1 bit fields in it.

The best I have been able to do with this was to use FieldOffset for the 8 and 16 bit fields. I then defined enums with the
FlagAttribute to generate the 1 and 2 bit fields.

Any suggestions or comments on the preceding are welcome.

Now, things get better.
As I said this structure comes on a communications line so if a BYTE (8 bits) contains certain invalid binary data, it is
escaped.with an escape BYTE. In my old C++ code, I simply allocated a structure of the correct size and copied the incoming bytes
to it skipping the escape bytes. For example, I might receive 40 bytes of data for the 36 bytes structure and 4 of the 40 bytes
would be escape bytes. After copy and dropping escape bytes, I would have 36 bytes in the correct location to access via C++
field names.

I need a way to do this C#. I would prefer to keep it as safe code. I am not sure that this code will be able to run everywhere
that it needs to run if it is unsafe.

I could do the same copy and drop using byte arrays, but I do not know how to get my 36 byte array into the structure.

Thanks for help and pointers.
-------------------------------------------
Roy Chastain
KMSYS Worldwide, Inc.
http://www.kmsys.com
Jul 25 '06 #1
9 2522
Roy,

Can you post the declaration of the old structure, as well as some of
the code you used to populate it from the line?
--
- Nicholas Paldino [.NET/C# MVP]
- mv*@spam.guard.caspershouse.com

"Roy Chastain" <ro*@kmsys.comwrote in message
news:p9********************************@4ax.com...
>I have a legacy structure that appears on a communications line that has 16
bit, 8 bit, 2 bit and 1 bit fields in it.

The best I have been able to do with this was to use FieldOffset for the 8
and 16 bit fields. I then defined enums with the
FlagAttribute to generate the 1 and 2 bit fields.

Any suggestions or comments on the preceding are welcome.

Now, things get better.
As I said this structure comes on a communications line so if a BYTE (8
bits) contains certain invalid binary data, it is
escaped.with an escape BYTE. In my old C++ code, I simply allocated a
structure of the correct size and copied the incoming bytes
to it skipping the escape bytes. For example, I might receive 40 bytes of
data for the 36 bytes structure and 4 of the 40 bytes
would be escape bytes. After copy and dropping escape bytes, I would have
36 bytes in the correct location to access via C++
field names.

I need a way to do this C#. I would prefer to keep it as safe code. I am
not sure that this code will be able to run everywhere
that it needs to run if it is unsafe.

I could do the same copy and drop using byte arrays, but I do not know how
to get my 36 byte array into the structure.

Thanks for help and pointers.
-------------------------------------------
Roy Chastain
KMSYS Worldwide, Inc.
http://www.kmsys.com

Jul 25 '06 #2
Thanks for the quick interest

This is the structure in C++
typedef struct
{ BYTE ctndl_class; // byte 0
BYTE ctndl_skip; // byte 1
BYTE ctndl_nolinefeed: 1; // byte 2 begin
BYTE ctndl_nocarriagereturn: 1;
BYTE ctndl_newpage: 1;
BYTE ctndl_skipline: 1;
BYTE ctndl_space: 1;
BYTE ctndl_blocked: 1;
BYTE ctndl_motionbefore: 1;
BYTE ctndl_tab: 1; // byte 2 end
BYTE ctndl_lsn[3]; // byte 3
BYTE ctndl_priorty; // byte 6
BYTE ctndl_unused1[5];
BYTE ctndl_unused2;
BYTE ctndl_textsize[2]; // byte 13
BYTE ctndl_unused3[9];
BYTE ctndl_frsn[3]; // byte 24
BYTE ctndl_original[3]; // byte 27
} CT_NDL_Type;

typedef struct
{ CT_NDL_Type ctndlf_ctndl;
BYTE ctndlf_unused[10];
} CT_NDL_FULL_Type;
This is the code in C++
void process_method

CT_NDL_FULL_Type header;
while (header_offset < T27_HEADER_SIZE)
{
if (((cur_char = the_recv_queue->GetChar()) != TC_IAC) || in_tc_iac)
{
in_tc_iac = false;
if (header_offset == 13)
hdr_msg_len = cur_char * 256;
if (header_offset == 14)
hdr_msg_len += cur_char;
*(LPBYTE(&header)+(header_offset++)) = cur_char;
}
else
in_tc_iac = true;
the_message_len--;
}

The TC_IAC is the escape byte.
Also I generate a message length from bytes 13 and 14 as I go through.
T27_HEADER_SIZE is the length of the CT_NDL_FULL_Type which
On Tue, 25 Jul 2006 12:01:38 -0400, "Nicholas Paldino [.NET/C# MVP]" <mv*@spam.guard.caspershouse.comwrote:
>Roy,

Can you post the declaration of the old structure, as well as some of
the code you used to populate it from the line?
-------------------------------------------
Roy Chastain
KMSYS Worldwide, Inc.
http://www.kmsys.com
Jul 25 '06 #3
Hi Roy,

Thank you for posting.

This is a quick note to let you know that I am performing research on this
issue and I will get back to you as soon as possible. I appreciate your
patience.
Sincerely,
Linda Liu
Microsoft Online Community Support

==================================================
Get notification to my posts through email? Please refer to
http://msdn.microsoft.com/subscripti...ult.aspx#notif
ications.

Note: The MSDN Managed Newsgroup support offering is for non-urgent issues
where an initial response from the community or a Microsoft Support
Engineer within 1 business day is acceptable. Please note that each follow
up response may take approximately 2 business days as the support
professional working with you may need further investigation to reach the
most efficient resolution. The offering is not appropriate for situations
that require urgent, real-time or phone-based interactions or complex
project analysis and dump analysis issues. Issues of this nature are best
handled working with a dedicated Microsoft Support Engineer by contacting
Microsoft Customer Support Services (CSS) at
http://msdn.microsoft.com/subscripti...t/default.aspx.
==================================================

This posting is provided "AS IS" with no warranties, and confers no rights.

Jul 26 '06 #4
Hi Roy,

In C#, you could declare an variable of a Structure and access each field
via the variable.

For example, you may define your C++ structure in C# like below.

struct CT_NDL_Type
{
public byte ctndl_class; // byte 0
public byte ctndl_skip; // byte 1

public byte ctndl_byte2; // replace
the following 8 field with one field of byte
//public byte ctndl_nolinefeed; // byte 2 begin
//public byte ctndl_nocarriagereturn;
//public byte ctndl_newpage;
//public byte ctndl_skipline;
//public byte ctndl_space;
//public byte ctndl_blocked;
//public byte ctndl_motionbefore;
//public byte ctndl_tab; // byte 2 end

public byte[] ctndl_lsn; // byte 3
public byte ctndl_priorty; // byte 6
public byte[] ctndl_unused1;
public byte ctndl_unused2;
public byte[] ctndl_textsize; // byte 13
public byte[] ctndl_unused3;
public byte[] ctndl_frsn; // byte 24
public byte[] ctndl_original; // byte 27

}

The code of defining a variable of this structure and accessing the
variable's field is listed below.

CT_NDL_Type var = new CT_NDL_Type();
var.ctndl_class = (byte)1;
var.ctndl_skip = (byte)2;

There're several problems here.

Firstly, there's no corresponding type for bit in C#. You could define the
byte2 as a single field of byte.

Secondly, those fields with an array should be initialize in the
constructor of the structure. Structure can declare constructors, but they
must take parameters. However, it will not make sense in our scenario. So I
recommend you to use a class instead of structure. You could declare a
contructor that doesn't take any parameter to initialize those fields with
an array. The code of declaring an instance of a class and accessing the
instance's field is the same as that for structure.

Hope this helps.
If you have any concerns, please feel free to let me know.
Sincerely,
Linda Liu
Microsoft Online Community Support
Jul 27 '06 #5
No, I am sorry, but this does not help at all.
I have no control of this structure. It has bit fields and fields that are 3 bytes long and that is that. Also remember that
when I first receive the data with this structure it in, it may have other bytes that have to be removed.

Constructors are the least of my worries. Right now a big help would be to be able define the structure/class so that the actual
memory occupied is the same as the original C++ structure including bit fields and 3 byte fields.

I really do not think that
public byte item1;
public byte [] item2;
public byte item3

allocates the same memory

byte item1;
byte item2[3];
byte item3;

I think the first one creates an object that is actually a pointer to a 3 byte array while the 2nd is just 3 consecutive bytes in
memory sandwiched in between item1 and item3.

Please explain to me if I have miss understood array allocation in the managed world.

On Thu, 27 Jul 2006 11:53:48 GMT, v-****@online.microsoft.com (Linda Liu [MSFT]) wrote:
>Hi Roy,

In C#, you could declare an variable of a Structure and access each field
via the variable.

For example, you may define your C++ structure in C# like below.

struct CT_NDL_Type
{
public byte ctndl_class; // byte 0
public byte ctndl_skip; // byte 1

public byte ctndl_byte2; // replace
the following 8 field with one field of byte
//public byte ctndl_nolinefeed; // byte 2 begin
//public byte ctndl_nocarriagereturn;
//public byte ctndl_newpage;
//public byte ctndl_skipline;
//public byte ctndl_space;
//public byte ctndl_blocked;
//public byte ctndl_motionbefore;
//public byte ctndl_tab; // byte 2 end

public byte[] ctndl_lsn; // byte 3
public byte ctndl_priorty; // byte 6
public byte[] ctndl_unused1;
public byte ctndl_unused2;
public byte[] ctndl_textsize; // byte 13
public byte[] ctndl_unused3;
public byte[] ctndl_frsn; // byte 24
public byte[] ctndl_original; // byte 27

}

The code of defining a variable of this structure and accessing the
variable's field is listed below.

CT_NDL_Type var = new CT_NDL_Type();
var.ctndl_class = (byte)1;
var.ctndl_skip = (byte)2;

There're several problems here.

Firstly, there's no corresponding type for bit in C#. You could define the
byte2 as a single field of byte.

Secondly, those fields with an array should be initialize in the
constructor of the structure. Structure can declare constructors, but they
must take parameters. However, it will not make sense in our scenario. So I
recommend you to use a class instead of structure. You could declare a
contructor that doesn't take any parameter to initialize those fields with
an array. The code of declaring an instance of a class and accessing the
instance's field is the same as that for structure.

Hope this helps.
If you have any concerns, please feel free to let me know.
Sincerely,
Linda Liu
Microsoft Online Community Support
-------------------------------------------
Roy Chastain
KMSYS Worldwide, Inc.
http://www.kmsys.com
Jul 28 '06 #6
Hi Roy,

Firstly, C# dose not supporrt bit fields.

Secondly, in .Net, you should initialize a array with initialization or
with the "new" keyword. The following is a sample.

Byte[] item = {1, 2, 3}; // allocate three elements' memory with
the values of 1, 2 and 3
Byte[] item = new Byte[3]; // just allocate three elements' memory

It's not like in C++ that you could initialize the array by the code
"Byte[3] item;".
I really do not think that
public byte item1;
public byte [] item2;
public byte item3
>allocates the same memory
>byte item1;
byte item2[3];
byte item3;
After you initialize the array items in the constructor, item2 is allocated
the same memory as it is in C++.

Thirdly, Class is of Reference type and Structure is Value type in .Net.
in C++ an array is merely a pointer. However, in C#, arrays are of
Reference type.

For more information on the difference between C# and C++, you may refer to
the link below.

http://msdn2.microsoft.com/en-us/lib...3b(d=ide).aspx

Hope this helps.
If you have anything unclear, please feel free to tell me.
Sincerely,
Linda Liu
Microsoft Online Community Support
Jul 31 '06 #7
There is no information below that I did not already know. That is why I did the original post.
Yes, I know C# does not handle bit fields.
Yes, I know that structures are value types and classes are reference types.
Yes, I know that arrays are references. (I would argue the point that arrays in C++ are pointers. Yes, they may be treated as
pointers, but in the case of my structure the structure has 3 bytes allocated in it for item2 and that is the important part.
Those 3 bytes are IN the structure; NOT somewhere else and POINTED to by the structure.)

Now, all that said, as I asked before.. Is there anyway to handle this legacy structure in C# or am I going to have to use
managed C++ to handle it and make extraction calls from C# to the C++ code.
On Mon, 31 Jul 2006 10:14:56 GMT, v-****@online.microsoft.com (Linda Liu [MSFT]) wrote:
>Hi Roy,

Firstly, C# dose not supporrt bit fields.

Secondly, in .Net, you should initialize a array with initialization or
with the "new" keyword. The following is a sample.

Byte[] item = {1, 2, 3}; // allocate three elements' memory with
the values of 1, 2 and 3
Byte[] item = new Byte[3]; // just allocate three elements' memory

It's not like in C++ that you could initialize the array by the code
"Byte[3] item;".
>I really do not think that
public byte item1;
public byte [] item2;
public byte item3
>>allocates the same memory
>>byte item1;
byte item2[3];
byte item3;

After you initialize the array items in the constructor, item2 is allocated
the same memory as it is in C++.

Thirdly, Class is of Reference type and Structure is Value type in .Net.
in C++ an array is merely a pointer. However, in C#, arrays are of
Reference type.

For more information on the difference between C# and C++, you may refer to
the link below.

http://msdn2.microsoft.com/en-us/lib...3b(d=ide).aspx

Hope this helps.
If you have anything unclear, please feel free to tell me.
Sincerely,
Linda Liu
Microsoft Online Community Support
-------------------------------------------
Roy Chastain
KMSYS Worldwide, Inc.
http://www.kmsys.com
Aug 2 '06 #8
Hi Roy,
Is there anyway to handle this legacy structure in C#?
I think you may redefine the legacy structure as a class in C# , use a byte
to represent the bit field because there's no bit field in C# and
initialize the byte array fields in the constructor. Below is a sample:

Class myNewStructure
{
public Byte Item1;
public Byte Item2; // item2 was a bit field in the
legacy structurer.
public Byte[] Item3;

public myNewStructure()
{
Item1 = 0;
Item2 = 0;
Item3 = new Byte[3];
}
}

You may define an instance of the class (i.e obj1) and access its public
field by the "." operator. For example, obj1.Item1 = (Byte)12;

Because you could not treat the instance of the class as a pointer, you
should assign each field with the codes as following:

obj1.Item1 = (Byte)12; // item1 is of type Byte
obj1.Item2 = (Byte)1; // item2 is of type Byte, but it make use of
only 1 bit of the byte
obj1.Item3[0] = (Byte)23; // item3 is of type Byte[ ]
obj1.Item3[1] = (Byte)24;
obj1.Item3[2] = (Byte)25;

Hope this helps.
If you have any concerns, please feel free to let me know.
Sincerely,
Linda Liu
Microsoft Online Community Support

Aug 4 '06 #9
Hi Roy,

Based on my understanding, you have developed a program in C++ for network
usage. You defined a structure in your program to receive the data passed
through the network. You have mentioned that there're 8 bit fields and byte
arrays in the structure. You receive the data from network and get the byte
array into the structure within a "while statement".

Now you want to do this in C#.

Unfortunately, there's no bit field in C#, so I recommend you combine the 8
bit fields into one byte in order to maintain the same memory layout as it
is in C++. As for the byte array in a strucutre, the memory layout is
different between C++ and C#. In C++, the byte array is located in the
strucutre. However, in C#, byte array is a reference variable and the
memory allocated for the byte array is out of the structure. In this case,
we couldn't use a "while statement" to get the byte array into the
structure and have to assign each field in the structure one by one.

I recommend you to use Class instead of Structure in C# in this issue.
There're two reasons. One is that the byte arrays need initializing and we
could do this in the constructor of the class. The second is that we could
define methods to get the byte array into the class and vice versa.

As for the "bit field", we could write a property of each "bit field" using
bit operation on the combined field.

The following is a sample for the definition of the class and the
properties for "bit fields".

class CT_NDL_Type
{
public byte ctndl_class;
public byte ctndl_skip;

public byte ctndl_field2; // combined
field;

public byte[] ctndl_lsn;
public byte ctndl_priorty;
public byte[] ctndl_unused1;
public byte ctndl_unused2;
public byte[] ctndl_textsize;
public byte[] ctndl_unused3;
public byte[] ctndl_frsn;
public byte[] ctndl_original;

public CT_NDL_Type()
{
// initialize the byte arrays in the constructor
ctndl_lsn = new byte[3];
ctndl_unused1 = new byte[5];
ctndl_textsize = new byte[2];
ctndl_unused3 = new byte[9];
ctndl_frsn = new byte[3];
ctndl_original = new byte[3];
}
// property for the first bit field
public byte bit1
{
get
{
return (byte)(ctndl_field2 & 0x01);
}
set
{
if (value == 0x1)
{
ctndl_field2 |= 0x01;
}
else if (value == 0x0)
{
ctndl_field2 &= 0xFE;
}
}
}
// property for the second bit field
public byte bit2
{
get
{
return (byte)((ctndl_field2 & 0x2) >1);
}
set
{
if (value == 0x1)
{
ctndl_field2 |= 0x02;
}
else if (value == 0x0)
{
ctndl_field2 &= 0xFD;
}
}
}
// property for the third bit field
public byte bit3
{
get
{
return (byte)((ctndl_field2 & 0x4) >2);
}
set
{
if (value == 0x1)
{
ctndl_field2 |= 0x4;
}
else if (value == 0x0)
{
ctndl_field2 &= 0xFB;
}
}
}
// property for the fourth bit field
public byte bit4
{
get
{
return (byte)((ctndl_field2 & 0x8) >3);
}
set
{
if (value == 0x1)
{
ctndl_field2 |= 0x8;
}
else if (value == 0x0)
{
ctndl_field2 &= 0xF7;
}
}
}
// property for the fifth bit field
public byte bit5
{
get
{
return (byte)((ctndl_field2 & 0x10) >4);
}
set
{
if (value == 0x1)
{
ctndl_field2 |= 0x10;
}
else if (value == 0x0)
{
ctndl_field2 &= 0xEF;
}
}
}
// property for the sixth bit field
public byte bit6
{
get
{
return (byte)((ctndl_field2 & 0x20) >5);
}
set
{
if (value == 0x1)
{
ctndl_field2 |= 0x20;
}
else if (value == 0x0)
{
ctndl_field2 &= 0xDF;
}
}
}
// property for the seventh bit field
public byte bit7
{

get
{
return (byte)((ctndl_field2 & 0x40 )>6);
}
set
{
if (value == 0x1)
{
ctndl_field2 |= 0x40;
}
else if (value == 0x0)
{
ctndl_field2 &= 0xBF;
}
}
}

// property for the eighth bit field
public byte bit8
{
get
{
return (byte)((ctndl_field2 & 0x80) >7);
}
set
{
if (value == 0x1)
{
ctndl_field2 |= 0x80;
}
else if (value == 0x0)
{
ctndl_field2 &= 0x7F;
}
}
}
}

We could assign the ctndl_field2 as a whole when we get the byte array into
the class and access the 8 bit fields using these properties. Below is a
sample code.

CT_NDL_Type var1 = new CT_NDL_Type();
var1.ctndl_field2 = 0x26;
MessageBox.Show(var1.bit1.ToString());

Hope this helps.
Sincerely,
Linda Liu
Microsoft Online Community Support

Aug 14 '06 #10

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

Similar topics

4
by: JellBell | last post by:
I dont know what is a legacy system..please help me out Posted Via Usenet.com Premium Usenet Newsgroup Services ---------------------------------------------------------- ** SPEED ** RETENTION...
2
by: Rajiv Kumar | last post by:
Hi, I am a Java prof for last 5 years and have delivered many enterprise application using J2EE. Now my company is making headway in the .NET area of the market, and I am trying to sort out few...
3
by: Sai Kit Tong | last post by:
I posted for help on legacy code interface 2 days ago. Probably I didn't make it clear in my original mail. I got a couple of answers but none of them address my issues directly (See attached...
3
by: Matt Laver | last post by:
Hi, I have a binary file that I'm currently reading byte by byte using code similiar to: string FileName = @"c:\myFile.dat"; FileStream fs = new FileStream(FileName, FileMode.Open,...
2
by: Mark Olbert | last post by:
First off, the sympathy is for all you poor buggers out there who have to figure out how to marry Managed Extensions for C++ onto your legacy code. My condolences; my brief experience with the...
12
by: gcary | last post by:
I am having trouble figuring out how to declare a pointer to an array of structures and initializing the pointer with a value. I've looked at older posts in this group, and tried a solution that...
4
by: Jason Madison | last post by:
I would like to create a .net application that still uses a few screens from an old legacy application we have. I can list records from the database in my .net app, but when it comes to making...
3
by: KeithR | last post by:
I am something of a newbie in the world of C# data structures, but I am writing an application that needs to call a legacy DLL using .net 1.1. That is no big deal mostly, but I am having trouble...
4
by: yugidnu | last post by:
Hi all, I have the following problem. I have to access different types of structures getting passed via a void pointer. I have the code snippet here. ...
0
by: DolphinDB | last post by:
Tired of spending countless mintues downsampling your data? Look no further! In this article, you’ll learn how to efficiently downsample 6.48 billion high-frequency records to 61 million...
0
by: ryjfgjl | last post by:
ExcelToDatabase: batch import excel into database automatically...
0
isladogs
by: isladogs | last post by:
The next Access Europe meeting will be on Wednesday 6 Mar 2024 starting at 18:00 UK time (6PM UTC) and finishing at about 19:15 (7.15PM). In this month's session, we are pleased to welcome back...
0
by: Vimpel783 | last post by:
Hello! Guys, I found this code on the Internet, but I need to modify it a little. It works well, the problem is this: Data is sent from only one cell, in this case B5, but it is necessary that data...
0
by: jfyes | last post by:
As a hardware engineer, after seeing that CEIWEI recently released a new tool for Modbus RTU Over TCP/UDP filtering and monitoring, I actively went to its official website to take a look. It turned...
0
by: ArrayDB | last post by:
The error message I've encountered is; ERROR:root:Error generating model response: exception: access violation writing 0x0000000000005140, which seems to be indicative of an access violation...
1
by: PapaRatzi | last post by:
Hello, I am teaching myself MS Access forms design and Visual Basic. I've created a table to capture a list of Top 30 singles and forms to capture new entries. The final step is a form (unbound)...
1
by: CloudSolutions | last post by:
Introduction: For many beginners and individual users, requiring a credit card and email registration may pose a barrier when starting to use cloud servers. However, some cloud server providers now...
0
by: Faith0G | last post by:
I am starting a new it consulting business and it's been a while since I setup a new website. Is wordpress still the best web based software for hosting a 5 page website? The webpages will be...

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.