PC Review


Reply
Thread Tools Rate Thread

Declare array size in Struct?

 
 
robert.waters
Guest
Posts: n/a
 
      20th Oct 2008
I have to parse a binary file having a number of fixed records, each
record containing datas in fixed positions. I would like to parse
this binary file into an array of structures having members that
represent those fields, so that I can access the records in a
meaningful way.
Using C, I would have defined a struct that I could cast a byte array
into, which held exactly one of these fixed records. The struct would
be defined as such:
struct rec {
char index[1] ;
char padding[50];
char name[28];
};
No big deal, (rec)char_array;.

I tried to do something similar in C#, and I am getting an error
telling me that:
"Array size cannot be specified in a variable declaration"

How might I create a data structure with fixed-size members at design
time?
Do I really have to encapsulate this into a class that contains logic
to parse the record sequentially when it's instantiated?

Thanks.
 
Reply With Quote
 
 
 
 
Kerem Gümrükcü
Guest
Posts: n/a
 
      20th Oct 2008
Hi Robert,

i think, you are looking for this (PInvoke Style):

[StructLayout(LayoutKind.Sequential,CharSet=CharSet.Ansi)
public struct rec
{
[MarshalAs(UnmanagedType.LPStr,SizeConst=1)]
string index; //could also be a byte
[MarshalAs(UnmanagedType.LPStr,SizeConst=50)]
string padding;//could also be a byte
[MarshalAs(UnmanagedType.LPStr,SizeConst=28)]
string name;//could also be a byte
}

then you go like this:

rec your_rec = (rec)
Marshal.PtrToStructure(ptrPointerToYourBytesBlockOfMemory,typeof(rec));
MessageBox.Show(your_rec.name);

Regards

Kerem

--
-----------------------
Beste Grüsse / Best regards / Votre bien devoue
Kerem Gümrükcü
Latest Project: http://www.codeplex.com/restarts
Latest Open-Source Projects: http://entwicklung.junetz.de
-----------------------
"This reply is provided as is, without warranty express or implied."
"robert.waters" <(E-Mail Removed)> schrieb im Newsbeitrag
news:9b88c175-3ba3-4339-8957-(E-Mail Removed)...
>I have to parse a binary file having a number of fixed records, each
> record containing datas in fixed positions. I would like to parse
> this binary file into an array of structures having members that
> represent those fields, so that I can access the records in a
> meaningful way.
> Using C, I would have defined a struct that I could cast a byte array
> into, which held exactly one of these fixed records. The struct would
> be defined as such:
> struct rec {
> char index[1] ;
> char padding[50];
> char name[28];
> };
> No big deal, (rec)char_array;.
>
> I tried to do something similar in C#, and I am getting an error
> telling me that:
> "Array size cannot be specified in a variable declaration"
>
> How might I create a data structure with fixed-size members at design
> time?
> Do I really have to encapsulate this into a class that contains logic
> to parse the record sequentially when it's instantiated?
>
> Thanks.


 
Reply With Quote
 
robert.waters
Guest
Posts: n/a
 
      20th Oct 2008
On Oct 20, 2:10*am, Kerem Gümrükcü <kareem...@hotmail.com> wrote:
> Hi Robert,
>
> i think, you are looking for this (PInvoke Style):
>
> [StructLayout(LayoutKind.Sequential,CharSet=CharSet.Ansi)
> public struct rec
> {
> * * [MarshalAs(UnmanagedType.LPStr,SizeConst=1)]
> * * string index; //could also be a byte
> * * [MarshalAs(UnmanagedType.LPStr,SizeConst=50)]
> * * string padding;//could also be a byte
> * * [MarshalAs(UnmanagedType.LPStr,SizeConst=28)]
> * * string name;//could also be a byte
>
> }
>
> then you go like this:
>
> rec your_rec = (rec)
> Marshal.PtrToStructure(ptrPointerToYourBytesBlockOfMemory,typeof(rec));
> MessageBox.Show(your_rec.name);
>
> Regards
>
> Kerem
>


Thank you, that's exactly what I needed.
 
Reply With Quote
 
robert.waters
Guest
Posts: n/a
 
      21st Oct 2008
On Oct 20, 2:10*am, Kerem Gümrükcü <kareem...@hotmail.com> wrote:
> Hi Robert,
>
> i think, you are looking for this (PInvoke Style):
>
> [StructLayout(LayoutKind.Sequential,CharSet=CharSet.Ansi)
> public struct rec
> {
> * * [MarshalAs(UnmanagedType.LPStr,SizeConst=1)]
> * * string index; //could also be a byte
> * * [MarshalAs(UnmanagedType.LPStr,SizeConst=50)]
> * * string padding;//could also be a byte
> * * [MarshalAs(UnmanagedType.LPStr,SizeConst=28)]
> * * string name;//could also be a byte
>
> }
>
> then you go like this:
>
> rec your_rec = (rec)
> Marshal.PtrToStructure(ptrPointerToYourBytesBlockOfMemory,typeof(rec));
> MessageBox.Show(your_rec.name);
>


I have a problem: I get an 'attempted to read protected memory"
exception.
[StructLayout(LayoutKind.Sequential,CharSet=CharSet.Ansi)]
public struct PbEntry // size=385b
{
[MarshalAs(UnmanagedType.LPStr,SizeConst=1)]
string index;
[MarshalAs(UnmanagedType.LPStr,SizeConst=5)]
string nameHeader;
[MarshalAs(UnmanagedType.LPStr,SizeConst=123)]
string contactName;
[MarshalAs(UnmanagedType.LPStr, SizeConst = 11)]
string numsHeader;
[MarshalAs(UnmanagedType.LPStr, SizeConst = 49)]
string cellNumber;
[MarshalAs(UnmanagedType.LPStr, SizeConst = 49)]
string homeNumber;
[MarshalAs(UnmanagedType.LPStr, SizeConst = 49)]
string workNumber;
[MarshalAs(UnmanagedType.LPStr, SizeConst = 49)]
string otherNumber1;
[MarshalAs(UnmanagedType.LPStr, SizeConst = 49)]
string otherNumber2;
}

...... program and FileStream ('fs') set-up .....

byte[] pbData = new byte[385];
fs.Read(pbData, 0, 385);
// pbData is now populated correctly
PbEntry pb=new PbEntry();
IntPtr ptr = Marshal.AllocHGlobal(pbData.Length);
try
{
Marshal.Copy(pbData, 0, ptr, pbData.Length);
pb = (PbEntry)Marshal.PtrToStructure(ptr,
typeof(PbEntry)); // exception happens here
Console.WriteLine(pb.ToString());
}
finally
{
Marshal.FreeHGlobal(ptr);
}

Any reason why that is protected memory?

Thanks!
 
Reply With Quote
 
robert.waters
Guest
Posts: n/a
 
      21st Oct 2008
On Oct 20, 7:16*pm, "robert.waters" <robert.wat...@gmail.com> wrote:
> On Oct 20, 2:10*am, Kerem Gümrükcü <kareem...@hotmail.com> wrote:
>
>
>
> > Hi Robert,

>
> > i think, you are looking for this (PInvoke Style):

>
> > [StructLayout(LayoutKind.Sequential,CharSet=CharSet.Ansi)
> > public struct rec
> > {
> > * * [MarshalAs(UnmanagedType.LPStr,SizeConst=1)]
> > * * string index; //could also be a byte
> > * * [MarshalAs(UnmanagedType.LPStr,SizeConst=50)]
> > * * string padding;//could also be a byte
> > * * [MarshalAs(UnmanagedType.LPStr,SizeConst=28)]
> > * * string name;//could also be a byte

>
> > }

>
> > then you go like this:

>
> > rec your_rec = (rec)
> > Marshal.PtrToStructure(ptrPointerToYourBytesBlockOfMemory,typeof(rec));
> > MessageBox.Show(your_rec.name);

>
> I have a problem: I get an 'attempted to read protected memory"
> exception.
> * * [StructLayout(LayoutKind.Sequential,CharSet=CharSet.Ansi)]
> * * public struct PbEntry *// size=385b
> * * {
> * * * * [MarshalAs(UnmanagedType.LPStr,SizeConst=1)]
> * * * * string index;
> * * * * [MarshalAs(UnmanagedType.LPStr,SizeConst=5)]
> * * * * string nameHeader;
> * * * * [MarshalAs(UnmanagedType.LPStr,SizeConst=123)]
> * * * * string contactName;
> * * * * [MarshalAs(UnmanagedType.LPStr, SizeConst = 11)]
> * * * * string numsHeader;
> * * * * [MarshalAs(UnmanagedType.LPStr, SizeConst = 49)]
> * * * * string cellNumber;
> * * * * [MarshalAs(UnmanagedType.LPStr, SizeConst = 49)]
> * * * * string homeNumber;
> * * * * [MarshalAs(UnmanagedType.LPStr, SizeConst = 49)]
> * * * * string workNumber;
> * * * * [MarshalAs(UnmanagedType.LPStr, SizeConst = 49)]
> * * * * string otherNumber1;
> * * * * [MarshalAs(UnmanagedType.LPStr, SizeConst = 49)]
> * * * * string otherNumber2;
> * * *}
>
> ..... program and FileStream ('fs') set-up .....
>
> * * * * * * * * byte[] pbData = new byte[385];
> * * * * * * * * fs.Read(pbData, 0, 385);
> * * * * * * * * // pbData is now populated correctly
> * * * * * * * * PbEntry pb=new PbEntry();
> * * * * * * * * IntPtr ptr = Marshal.AllocHGlobal(pbData.Length);
> * * * * * * * * try
> * * * * * * * * {
> * * * * * * * * * * Marshal.Copy(pbData, 0, ptr, pbData.Length);
> * * * * * * * * * * pb = (PbEntry)Marshal.PtrToStructure(ptr,
> typeof(PbEntry)); // exception happens here
> * * * * * * * * * * Console.WriteLine(pb.ToString());
> * * * * * * * * }
> * * * * * * * * finally
> * * * * * * * * {
> * * * * * * * * * * Marshal.FreeHGlobal(ptr);
> * * * * * * * * }
>
> Any reason why that is protected memory?
>
> Thanks!


Replacing UnmanagedType.LPStr with UnmanagedType.ByValTStr for each
struct member fixed this problem.
Does anyone have any idea why?
Note: the data inside the records had many nulls (\0), which I figured
wouldn't be a problem because they typically follow strings of non-
null characters, and so would fit the model of 'null-terminated ANSI
character string'.
Thank you for any input that would help.
 
Reply With Quote
 
 
 
Reply

Thread Tools
Rate This Thread
Rate This Thread:

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
how to send a variable size VBA array to a C struct Brian Murphy Microsoft Excel Programming 5 30th Apr 2009 04:07 AM
Obtaining size of struct array-type member from fixed pack=1 struct? taskswap@gmail.com Microsoft C# .NET 4 12th Jan 2006 02:58 PM
Marshal struct with array size fixed of other struct (MyStruct[X]) Cyril Microsoft C# .NET 2 17th Nov 2005 08:55 AM
How to get the size when a struct array in aother struct ? SleepSheep Microsoft C# .NET 1 27th May 2004 08:14 AM
Marshaling struct containing pointer to array of arrays of struct =?Utf-8?B?SmVmZg==?= Microsoft C# .NET 0 20th May 2004 04:36 PM


Features
 

Advertising
 

Newsgroups
 


All times are GMT +1. The time now is 01:32 PM.