2010-07-14 9 views
6

में एक संरचना में बाइट्स पढ़ना। मैं अपने छोटे 3 डी इंजन प्रोजेक्ट के लिए एक एमडी 2 लोडर लिख रहा हूं। मेरी पुरानी भाषा में (सी) मैं एक संरचना को परिभाषित कर सकता हूं और फिर खुली फ़ाइल से सीधे संरचना में पढ़ सकता हूं।दीवार प्रश्न से दूसरे के लिए सी #

[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; 
} 

मेरे पाठक कोड में, मैं की तरह कुछ करना चाहते हैं: इस प्रकार मैं एक संरचना MD2 फ़ाइल से हेडर सूचना धारण करने के लिए है

// 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)); 

मुझे पता है यह सही नहीं है , क्योंकि यह कुछ हद तक अजीब प्रकार की सुरक्षा को तोड़ता है, लेकिन आपको यह पता चलता है कि मैं क्या हासिल करना चाहता हूं। मैं पाठक को अलग-अलग कॉल के साथ ऐसा कर सकता हूं। ReadInt32(), लेकिन अगर मैं सामान्य लाइब्रेरी कॉल का उपयोग कर रहा हूं, तो काम करने के लिए वैसे भी उत्सुक हूं।

मैंने मार्शल.कोपी() विधि में थोड़ा सा देखा है, लेकिन ऐसा लगता है कि यह प्रबंधित और अप्रबंधित स्मृति के बीच जा रहा है, जो वास्तव में मैं यहां नहीं कर रहा हूं।

कोई सुझाव?

+0

किसी तरह लग रहा है के लिए एक इसी पद यह करने के लिए आप को हरा: http://gpwiki.org/index.php/C_sharp:MD2_loader_in_CSharp – Jess

उत्तर

3

सी में एक संरचना और सी # में एक संरचना दो पूरी तरह से अलग चीजें हैं। सी में एक संरचना मूल्य प्रकार और संदर्भ प्रकार दोनों के लिए उपयोग की जाती है, जबकि सी # में एक संरचना केवल मूल्य प्रकारों के लिए उपयोग की जाती है।

एक मान प्रकार को एक मान का प्रतिनिधित्व करना चाहिए, लेकिन आपके पास जो कुछ है वह बहुत सारे मूल्य हैं, इसलिए आपको इसके बजाय कक्षा का उपयोग करना चाहिए। .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); 
    } 

} 
+0

मैं आगे बढ़ गया और इस विधि का उपयोग किया, मैं मूल्य और संदर्भ प्रकारों के बीच अपने भेद के साथ पूरी तरह से सहमत हूं । आपका समाधान बेहतर डिज़ाइन है, निश्चित रूप से, अगर मैं चीजों को करने की अपनी पुरानी शैली का अनुकरण करने के लिए एक आसान तरीका था तो मैं केवल उत्सुक था। :-) –

+0

-1 ... उचित उत्तरों को पूरी तरह अनदेखा कर रहा है जो इंगित करता है कि विशेष रूप से इंटरऑप कारणों के लिए समर्थित है। – TomTom

+0

@ क्रिस: यह संभव है, लेकिन उतना आसान नहीं है। आपको उन गुणों का उपयोग करने की आवश्यकता होगी जो यह निर्धारित करने के लिए संरचना में व्यवस्थित होते हैं कि कोई पैडिंग नहीं है और वे सही क्रम में हैं। फिर आपको मेमोरी में डेटा पिन करने के लिए कचरा कलेक्टर का उपयोग करने की आवश्यकता है, और डेटा को संरचना में कॉपी करने के लिए मार्शलिंग या असुरक्षित कोड। – Guffa

0

यह सी # में थोड़ा जटिल हो सकता है, लेकिन आप चीजों को सेट अप कर सकते हैं जहां आप बाइट सरणी से बाइट्स को संरचना में याद कर सकते हैं।

1

आप क्या कर सकते approprate आकार का एक बफर में बाइट्स पढ़ा जाता है, fixed (int* = &md2hdr.FourCC) का उपयोग अपने संरचना के शुरू करने के लिए सूचक प्राप्त करने के लिए, byte* करने के लिए अपने संरचना करने के लिए सूचक डाली, और मैन्युअल रूप से बाइट्स की प्रतिलिपि बनाएँ।

5

, बाइट सरणी के लिए बाइट धारा पढ़ें यह packet नाम दें, और निम्न प्रयास करें:

GCHandle pinned = GCHandle.Alloc(packet, GCHandleType.Pinned); 
MD2_Header h = (MD2_Header)Marshal.PtrToStructure(pinned.AddrOfPinnedObject(), typeof(MD2_Header)); 
pinned.Free(); 
+0

इस गतिरोध उत्पन्न जीसी एक बहुत ही महत्वपूर्ण तरीके से, कुछ मैं टालना चाहता हूं। –

3

आप एक शॉट में अपनी संरचना में Marshal.PtrToStructure का उपयोग एक सूचक सीधे से नकल कर सकते हैं।

byte[] data = reader.ReadBytes(...); 
fixed (byte* bytes = data) 
{ 
    Classic.Util.MD2_Header md2hdr = 
      (Classic.Util.MD2_Header)Marshal.PtrToStructure(
       Marshal.UnsafeAddrOfPinnedArrayElement(data, 0), 
       typeof(Classic.Util.MD2_Header) 
     ); 
} 
+0

यह यॉसियन के समाधान की तुलना में थोड़ा क्लीनर है, लेकिन अभी भी जीसी के साथ बहुत परेशान होना शामिल है, बल्कि इससे बचने के लिए। इसके अलावा, एक "निश्चित" खंड को/unsafe पैरामीटर के साथ संकलन की आवश्यकता होती है। –

+0

@ क्रिस डी: बहुत अधिक बार जब आप बाइट्स के साथ गड़बड़ कर रहे हैं और सीधे स्मृति की प्रतिलिपि बनाने की कोशिश कर रहे हैं, तो आपको ~ असुरक्षित होना चाहिए। ऐसा कहा जा रहा है, आप इसे अन्यथा कॉपी करने के द्वारा कर सकते हैं, लेकिन यह शायद आपके प्रश्न का सबसे सीधा जवाब है, आईएमओ ... –

1

आप नकल संभाल को मार्शलिंग इस्तेमाल कर सकते हैं। इसे संभालने के लिए कोड लिखने की जरूरत नहीं है।

//create object 
Classic.Util.MD2_Header md2hdr = new Classic.Util.MD2_Header(); 
Classic.Util.MD2_Header another = new Classic.Util.MD2_Header(); 
byte[] mem = new byte[Marshal.SizeOf(typeof(MD2_Header))]; 

//allocate unmanaged memory 
IntPtr hmem = Marshal.AllocHGlobal(Marshal.SizeOf(typeof(Classic.Util.MD2_Header))); 

//copy structure to unmanaged memory 
Marshal.StructureToPtr(md2hdr, hmem, false); 

//copy to managed memory 
Marshal.Copy(hmem, mem, 0, mem.Length); 

//copy unmanaged memory to structure 
another = (Classic.Util.MD2_Header)Marshal.PtrToStructure(hmem, typeof(Classic.Util.MD2_Header)); 

//free unmanaged memory 
Marshal.FreeHGlobal(hmem); 
+0

जेएस लिब एसओ आपके कोड को पहचानने के लिए रंग स्वरूपण स्वचालित है। ऐसा लगता है कि आप यहां कुछ बोल्ड को बोल्ड करने के लिए सेट कर रहे हैं, जो इसे फेंक सकता है ... –

+0

असल में, मैंने आपकी टिप्पणी के स्रोत को देखा और आप इसे गलत कर रहे हैं। स्रोत के लिए, एसओ पर, आपको बस इतना करना है कि कोड से पहले लाइन ब्रेक करना होगा और चार रिक्त स्थान से अपने कोड की लाइनों को इंडेंट करना होगा। बाकी स्वचालित है। हालांकि, आप कुछ पंक्तियों को बोल्ड नहीं कर सकते हैं। –

+0

मूल रूप से मैंने बोल्ड छोड़ दिया लेकिन बाद में इसे रखा जब मुझे मुख्य भागों को हाइलाइट करने के लिए रंगीन अधिकार नहीं मिला। मैं अब रंग प्राप्त करने के लिए इसे ठीक करने की कोशिश करूंगा। धन्यवाद। :) –

1

मुझे पता है कि आपके पास पहले से ही जवाब है और यह एक अच्छा जवाब है।

मैंने सोचा कि आपको ब्लॉग पोस्ट से कुछ मूल्य मिल सकता है, मैंने इसे प्राप्त करने के लिए .NET में उपलब्ध कुछ विकल्पों पर किया था।

Structure from binary data

और रिवर्स

Binary data from a structure

+1

इन लिंक के लिए धन्यवाद, वे अच्छे पढ़ रहे हैं। –

संबंधित मुद्दे