时间换另一个问题.我正在为我的小型3D引擎项目编写MD2加载程序.在我的旧语言(C)中,我可以定义一个结构,然后从打开的文件中直接读取()到结构中.我有一个结构来保存MD2文件中的标题信息,如下所示:
[StructLayout(LayoutKind.Sequential)] public struct MD2_Header { public int FourCC; public int Version; public int TextureWidth; public int TextureHeight; public int FrameSizeInBytes; public int NbrTextures; public int NbrVertices; public int NbrTextureCoords; public int NbrTriangles; public int NbrOpenGLCmds; public int NbrFrames; public int TextureOffset; public int TexCoordOffset; public int TriangleOffset; public int FrameOffset; public int OpenGLCmdOffset; public int EndOffset; }
在我的读者代码中,我想做的事情如下:
// Suck the MD2 header into a structure,it is 68 bytes long. Classic.Util.MD2_Header md2hdr = new Classic.Util.MD2_Header(); md2hdr = reader.ReadBytes(sizeof(Classic.Util.MD2_Header));
我意识到这是不正确的,因为它有点奇怪地打破了类型安全,但你知道我想要完成什么.我可以通过单独调用reader.ReadInt32()来做到这一点,但我很好奇是否有任何方式让我按照我希望使用普通库调用的方式工作.
我看了一下Marshal.Copy()方法,但似乎是在托管和非托管内存之间进行,这不是我在这里做的.
有什么建议?
解决方法
C中的结构和C#中的结构是两个完全不同的东西. C中的结构既用于值类型又用于引用类型,而C#中的结构仅用于值类型.
值类型应该表示单个值,但是您拥有的是大量值,因此您应该使用类. .NET中结构的建议最大大小为16个字节,您的数据量是其四倍以上.
public class MD2_Header { public int FourCC { get; set; } public int Version { get; set; }; public int TextureWidth { get; set; }; public int TextureHeight { get; set; }; public int FrameSizeInBytes { get; set; }; public int NbrTextures { get; set; }; public int NbrVertices { get; set; }; public int NbrTextureCoords { get; set; }; public int NbrTriangles { get; set; }; public int NbrOpenGLCmds { get; set; }; public int NbrFrames { get; set; }; public int TextureOffset { get; set; }; public int TexCoordOffset { get; set; }; public int TriangleOffset { get; set; }; public int FrameOffset { get; set; }; public int OpenGLCmdOffset { get; set; }; public int EndOffset { get; set; }; public MD2_Header(byte[] values) { FourCC = BitConverter.ToInt32(values,0); Version = BitConverter.ToInt32(values,4); TextureWidth = BitConverter.ToInt32(values,8); TextureHeight = BitConverter.ToInt32(values,12); FrameSizeInBytes = BitConverter.ToInt32(values,16); NbrTextures = BitConverter.ToInt32(values,20); NbrVertices = BitConverter.ToInt32(values,24); NbrTextureCoords = BitConverter.ToInt32(values,28); NbrTriangels = BitConverter.ToInt32(values,32); NbrOpenGLCmds = BitConverter.ToInt32(values,36); NbrFrames = BitConverter.ToInt32(values,40); TextureOffset = BitConverter.ToInt32(values,44); TexCoordOffset = BitConverter.ToInt32(values,48); TriangleOffset = BitConverter.ToInt32(values,52); FrameOffset = BitConverter.ToInt32(values,56); OpenGLCmdOffset = BitConverter.ToInt32(values,60); EndOffset = BitConverter.ToInt32(values,64); } }