Need help to convert
Hi i have tried to convert the c++ code below to c# but i don seem to get it right.
I got this below in .h header filepublic:
unsigned char inquiry_data[256];
Then the .cpp file
sa = (PSCSI_ADDRESS)&inquiry_data[0];
When i Go Definition of the (PSCSI_ADDRESS
) i got this below:
typedef struct _SCSI_ADDRESS {
ULONG Length;
UCHAR PortNumber;
UCHAR PathId;
UCHAR TargetId;
UCHAR Lun;
} SCSI_ADDRESS, *PSCSI_ADDRESS;
The below are what i have tried to convert to C#
public byte[] inquiry_data = new byte[256];
public class SCSI_ADDRESS
{
public ulong Length;
public byte PortNumber;
public byte PathId;
public byte TargetId;
public byte Lun;
}
sa = (SCSI_ADDRESS)inquiry_data[0];
However, i keep getting errors at the line (SCSI_ADDRESS)inquiry_data[0];
with error Cannot convert type 'byt开发者_高级运维e' to 'project1.Class.SCSI_ADDRESS'
Could you please advice?
C# cannot do data cast as C++ does. While fixed typed, C++ isn't actually strong typed -- you can cast whatever you want to whatever you need.
Now, with C#, things are more complicated, because C# struggles not to enable the user to do unsafe stuff. What are you trying to do is getting a bytestream and say to the compiler, "treat it as a SCSI_ADDRESS
.
To do this is C# you can either use serialization or unsafe sections. A quick and dirty (very dirty) way of doing this is described here in short.
Here is an I gave answer to a similar question.
Object to Network serialization - with an existing protocol
And a link to an article I did years ago on the options
http://taylorza.blogspot.com/2010/04/archive-structure-from-binary-data.html
And this one for doing the reverse
http://taylorza.blogspot.com/2010/04/archive-binary-data-from-structure.html
What are you trying to do is not possible in C#. The first issue is a typing issue. The compiler will not allow you to make a cast that it cannot verify as being valid. This is for type safety.
Even if we ignore the complier's role you get into an issue with how that data is represented in memory. Since C# is managed language how data exists in memory is not under your control. Unlike in C++ a struct will not take up exactly the memory that is allocated to it. There is some inherent overhead of memory space for the object itself. So from the very beginning you are misaligned and your information would not converted in the way you expect.
Jon Skeet recently had a blog post about the size of objects. Although this isn't exactly what you are trying to do it illustrates a couple fundamental flaws. 1) Depending upon if you are using the 32-bit of 64-bit version of .Net the size of of your object will be different. This means there is no way to have consistent behavior unless you wrote different versions of your program for the different .Net implementations. Even then there is no guarantee of the behavior Jon observed, this is something that you should not care about. 2) The size of the object is rounded to a byte boundary. So even if there was no overhead for the object itself, the size of the object is not necessarily the sum of the parts, it may in fact be larger.
I would solve that in the following way:
First I would make a class:
class SCSI_ADDRESS
{
public ulong Length;
public byte PortNumber;
public byte PathId;
public byte TargetId;
public byte Lun;
public SCSI_ADDRESS(ulong Length, byte PortNumber, byte PathId, byte TargetId, byte Lun)
{
this.Length = Length;
this.PortNumber = PortNumber;
this.PathId = PathId;
this.TargetId = TargetId;
this.Lun = Lun;
}
}
Then in the main method I would do the following.
static void Main(string[] args)
{
Object[] o = new Object[256];
SCSI_ADDRESS sa = new SCSI_ADDRESS(10, 1, 1, 1, 1); //example
o[0] = sa;
}
I hope that helps!
For a start, that C++ code is relying on undefined behaviour. You cannot cast arbitrary sections of memory to complex types and then attempt to access them.
C# does not allow arbitrary casts like that. If you are interested in turning raw bytes into data, you want to look into C# serialization.
public class SCSI_ADDRESS
{
public uint Length; // 4 bytes, (uint in C# == ulong in C++)
public byte PortNumber; // 1 byte
public byte PathId; // 1 byte
public byte TargetId; // 1 byte
public byte Lun; // 1 byte
// Total: 8 bytes
}
// 256 / sizeof(SCSI_ADDRESS) == 256 / 8 == 32
public SCSI_ADDRESS[] inquiry_data = new byte[256 / sizeof(SCSI_ADDRESS)];
sa = inquiry_data[0];
精彩评论