.NET

2010-03-11 5 views
9

में संरचनाओं का आकार मेरी समस्या सी से सी # प्रोग्राम में किसी प्रोग्राम के बीच संरचना भेजने के लिए है।.NET

मैं सी # में एक संरचना बनाया:

public struct NetPoint { 
    public float lat; // 4 bytes 
    public float lon; // 4 bytes 
    public int alt; // 4 bytes 
    public long time; // 8 bytes 
} 

संरचना का कुल आकार 20 बाइट होना चाहिए।

जब मैं इस संरचना का सी ++ में एक sizeof(),

System.Diagnostics.Debug.WriteLine(
    "SizeOf(NetPoint) = " + 
    System.Runtime.InteropServices.Marshal.SizeOf(new NetPoint())); 

डिबग सांत्वना से पता चलता है:

sizeof (NetPoint) = 24

लेकिन मैं होने की संभावना 20 बाइट्स मुझे एक अंतर क्यों दिखता है?

+0

यहाँ देखें: http://www.vsj.co.uk/articles/display.asp?id=501 –

उत्तर

7

दरअसल, तकनीकी रूप से संरचना न्यूनतम 20 बाइट्स होना चाहिए। यदि आप भेजते समय अधिक आवंटित करते हैं, तो रिसीवर सिर्फ उनका उपयोग/प्रतिलिपि नहीं करेगा। समस्या हमेशा घटती है।

उसने कहा, मुझे समस्या दिखाई देती है। हम्म। मुझे लगता है कि समस्या आखिरी लंबी है .... जो आईएमएचओ आठ बाइट्स से गठबंधन हो जाती है, इससे पहले चार खाली बाइट इंजेक्शन होती है। मुझे लगता है कि आठ-बाइट तत्व को आठ-बाइट सीमा से गठबंधन करने के लिए प्रदर्शन दंड नहीं है।

StructLayout संलग्न करें प्रत्येक तत्व के ऑफसेट को मैन्युअल रूप से निर्धारित करने के लिए। फिर आप चीजों को लाइन में प्राप्त करने में सक्षम होना चाहिए।

संदर्भ: How to control the physical layout of the data fields in the .NET Framework 2.0

[StructLayout(LayoutKind.Sequential, Pack=1)] 
public struct NetPoint { 
    public float lat; // 4 bytes 
    public float lon; // 4 bytes 
    public int alt; // 4 bytes 
    public long time; // 8 bytes 
} 

कि कम से कम एक-बाइट सीमा के तत्वों संरेखित चाहिए। यदि आवश्यक हो तो भी आप प्रत्येक तत्व की सटीक शुरुआत को परिभाषित करके आगे जा सकते हैं।

+0

आपका समाधान भी काम करता है। आपका बहुत बहुत धन्यवाद। आपका समाधान जॉन के जवाब से आसान लगता है। मैं आपके समाधान का उपयोग करूंगा .. अलविदा – user291830

2

विशेषता जोड़ने का प्रयास करें [स्ट्रक्चरलाइट (लेआउटकिंड.Sequential, पैक = 1)] और देखें कि क्या होता है। मुझे 8 बाइट पैडिंग पर संदेह है, इसलिए यह 3x8 बाइट्स है।

+1

नहीं, वस्तु .net में (पूर्णांक की तरह पुरातन को छोड़ कर) की राशि से आकार अधिक है खेत। – Andrey

9

एक सामान्य नियम के रूप में, सीपीयू को उस स्थान पर स्मृति में गठबंधन करने की आवश्यकता होती है जो उनके आकार का एक से अधिक है, इसलिए चार-बाइट पूर्णांक स्मृति स्मृति पर होना चाहिए जो चार से विभाजित है, और आठ -byte long आठ से विभाजित पते पर होना चाहिए।

सी # (और सी ++) भाषा डिजाइनर इसे जानते हैं, और वे आवश्यक संरेखण प्रदान करने के लिए संरचनाओं में पैडिंग डालेंगे।

public struct NetPoint { 
    public float lat;   // 4 bytes Offset 0 
    public float lon;   // 4 bytes Offset 4 
    public int alt;   // 4 bytes Offset 8 
    int to_preserve_alignment; // 4 bytes Offset 12 
    public long time;   // 8 bytes Offset 16 
} 

आप, एक नियम के रूप में, लंबे समय से पहले मान बनाकर इसे ठीक कर सकते, तो आप हमेशा अपने संरचनाओं की शुरुआत में सबसे बड़ा मान रखा है, तुम जीते: तो अपने संरचना की वास्तविक लेआउट इस तरह दिखता है सदस्यों के संरेखण को संरक्षित रखने के लिए कोई पैडिंग डाली नहीं है।

तुम भी संरचना घोषणा से पहले

[StructLayout(LayoutKind.Sequential, Pack = 4)] 

जोड़कर इसे ठीक कर सकते हैं, लेकिन है कि में परिणाम होगा गलत गठबंधन long time जो प्रदर्शन दर्द होता है।कुछ सीपीयू पर यह प्रदर्शन को बहुत दर्द देता है। (मिसाल वाले सदस्यों पर गलती होगी, उदाहरण के लिए)। x86 सीपीयू के पास केवल मामूली प्रदर्शन जुर्माना है, लेकिन भविष्य में सीपीयू का एक बड़ा प्रदर्शन जुर्माना होने का खतरा है, इसलिए यदि आप कर सकते हैं तो ठीक से संरेखित करने के लिए अपनी संरचनाओं को डिजाइन करना सबसे अच्छा है।

+0

आपके पास पूर्ण अधिकार है! बहुत बहुत धन्यवाद – user291830

+1

वाह, मुझे इस प्रकार की प्रतिक्रिया पसंद है। मैंने अभी कुछ नया और दिलचस्प सीखा। –

1

टॉमटॉम ने इस सवाल का जवाब दिया है, लेकिन एक और विकल्प है यदि आप एक मुश्किल COM इंटरऑप संरचना स्थिति में समाप्त होते हैं। फ़ील्डऑफसेट विशेषताओं का उपयोग करके प्रत्येक फ़ील्ड को अपने आप पर गठबंधन किया जा सकता है।

[StructLayout(LayoutKind.Explicit)] 
public struct COMPoint 
{ 
    [FieldOffset(0)] public int X; 
    [FieldOffset(4)] public int Y; 
} 
संबंधित मुद्दे