views:

191

answers:

2

Hello,

Awhile ago I asked you another question(Click here to view the question).

This is my problem when using that source file you gave me:

public unsafe struct tPacket_5000_E
{
    public Int16 size;
    public Int16 opcode;
    public byte securityCount;
    public byte securityCRC;
    public byte flag;
    fixed byte blowfish[8];  //Please NOTE THIS
    public Int32 seedCount;
    public Int32 seedCRC;
public fixed Int32 securityseed[19];
};

The struct is marked as "Unsafe" ,because of the blowfish array.I couldn't find any other way to declare an array inside structure.

The problem: When I parse the packet into that structure,the function doesn't put anything in blowfish[8],it's like it doesnt exist.Instead it puts the bytes in seedCount and seedCRC instead in blowfish or securityseed. They are always empty

This is my code:

 tPacket_5000_E packet = new tPacket_5000_E();
 packet = (tPacket_5000_E)CDynamicCastHelper.CastIntoFields(packet, data2, CastOptions.ReverseDWord | CastOptions.ReverseDWord);

Why it doesn't work for arrays? Is it ,because it's unsafe?

Thanks in advance!

+1  A: 

Look at MarshalAs attribute instead.

leppie
I misunderstood,where should i look?
John
A quick search here on SO, will provide an answer.
leppie
If i write this: [MarshalAsAttribute(UnmanagedType.ByValArray, SizeConst = 8)] public byte[] blowfish;It crash in the CDynamicCastHelper.cs
John
You would need to do the securityseed[19] too!
leppie
I created a new structure "test" with only that member - same problemPlease note this link: http://varjabedian.net/archive/2008/07/29/casting-a-byte-array-into-structures-in-c.aspxThe author of the file explained how to paste arrays in structures containing an array,but it doesnt work either. :(
John
Can you perhaps post the exact C declaration of the struct? From there I can help you convert it, using the Marshal class.
leppie
A: 

DynamicCastHelper uses the attribute DynamicCastHelperSizeAttribute to tell it what the size of an array field is - no need to make it fixed. It uses Reflection to work out what the fields of the struct/class are and the above mentioned attribute tells it the size of arrays.

You need to make some changes in CDynamicCastHelper.cs for it to work: (a) Reflection tells you byte or byte[] are System.Byte and System.Byte[] respectively. So where code is looking for type "byte[]", change this to "System.Byte[]". System.Byte is equivalent to byte. (b) In function _GenerateFieldsCast, it checks to see if each field is a class or a primitve type. System.Byte[] has IsClass equal to true, so you need to explicitly force System.Byte[] to be handled as a primitive type (so that the binary reader will read directly into it):

if (objField.FieldType.IsClass && objField.FieldType != typeof(System.Byte[]))

Example of usage:

public class SampleClass2b
{
    public Int16 a;
    [DynamicCastHelperSizeAttribute(5)]
    public byte[] ba; //{ get; set; }
    [DynamicCastHelperSizeAttribute(4)]
    public byte[] bb; //{ get; set; }
    public Int32 c;
}
byte[] data2b = new byte[] { 0, 17, 2, 3, 4, 5, 6, 7, 8, 9, 10, 0, 0, 0, 10 };
SampleClass2b clas2b = new SampleClass2b();
CDynamicCastHelper.CastIntoFields(clas2b, data2b, CastOptions.ReverseDWord | CastOptions.ReverseWord);
Mr.Dirty.Birdy