您好我试图将下面的c ++代码转换为c#,但我似乎没有把它弄好 我在.h头文件中得到了这个
public:
unsigned char inquiry_data[256];
然后是.cpp文件
sa = (PSCSI_ADDRESS)&inquiry_data[0];
当我去(PSCSI_ADDRESS
)的定义时,我得到了以下内容:
typedef struct _SCSI_ADDRESS {
ULONG Length;
UCHAR PortNumber;
UCHAR PathId;
UCHAR TargetId;
UCHAR Lun;
} SCSI_ADDRESS, *PSCSI_ADDRESS;
以下是我试图转换为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];
但是,我一直在第(SCSI_ADDRESS)inquiry_data[0];
行收到错误,错误为Cannot convert type 'byte' to 'project1.Class.SCSI_ADDRESS'
你可以请一下建议吗?
答案 0 :(得分:1)
C#不能像C ++那样进行数据转换。虽然固定类型,但C ++实际上并不是强类型的 - 你可以根据需要投射任何你想要的东西。
现在,使用C#,事情变得更复杂,因为C#努力不让用户做不安全的事情。您要做的是获取字节流并对编译器说“将其视为SCSI_ADDRESS
。
要做到这一点,C#可以使用序列化或不安全的部分。简而言之,here描述了一种快速而肮脏(非常脏)的方法。
答案 1 :(得分:1)
以下是我对类似问题的回答。
Object to Network serialization - with an existing protocol
链接到我多年前就选项
做过的文章http://taylorza.blogspot.com/2010/04/archive-structure-from-binary-data.html
这一个用于反向
http://taylorza.blogspot.com/2010/04/archive-binary-data-from-structure.html
答案 2 :(得分:1)
在C#中,你想做什么是不可能的。第一个问题是打字问题。编译器不允许您进行无法验证为有效的强制转换。这是为了类型安全。
即使我们忽略了编译器的角色,您也会遇到如何在内存中表示数据的问题。由于C#是托管语言,因此内存中的数据不受您的控制。与C ++不同,struct不会完全占用分配给它的内存。对象本身存在内存空间的固有开销。因此,从一开始你就没有对齐,你的信息也不会以你期望的方式转换。
Jon Skeet recently had a blog post about the size of objects。虽然这并不是你想要做的,但它说明了一些基本的缺陷。 1)根据您是否使用32位64位版本的.Net,对象的大小会有所不同。这意味着除非您为不同的.Net实现编写了不同版本的程序,否则无法获得一致的行为。即便如此,也无法保证Jon观察到的行为,这是你不应该关心的事情。 2)对象的大小四舍五入为字节边界。因此,即使对象本身没有开销,对象的大小也不一定是各部分的总和,实际上可能更大。
答案 3 :(得分:1)
我会用以下方式解决这个问题:
首先我会上课:
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;
}
}
然后在主要方法中,我将执行以下操作。
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;
}
我希望有所帮助!
答案 4 :(得分:0)
首先,该C ++代码依赖于未定义的行为。您不能将任意内存部分转换为复杂类型,然后尝试访问它们。
C#不允许这样的任意演员。如果您有兴趣将原始字节转换为数据,则需要查看C# serialization。
答案 5 :(得分:0)
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];