/ / बाइट ऑर्डर के आधार पर लंबे समय तक संरचना? - अजगर, अजगर- 2.7, संरचना

बाइट ऑर्डर के आधार पर लंबे समय तक संरचना की लंबाई? - अजगर, अजगर-2.7, संरचना

मैं उपयोग करना चाहता हूँ struct.unpack() पायथन 2.7 में एक बाइट स्ट्रिंग से एक लंबा मूल्य प्राप्त करने के लिए, लेकिन मुझे कुछ अजीब व्यवहार मिला और मैं यह जानना चाहूंगा कि क्या यह बग है या नहीं, और इसके अलावा, मैं इसे प्राप्त करने के लिए क्या कर सकता हूं।

क्या होता है निम्नलिखित:

import struct
>>> struct.unpack("L","")
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
struct.error: unpack requires a string argument of length 8

यह अपेक्षित व्यवहार है। यह 8-बाइट लंबे मूल्य निकालने के लिए 8-बाइट स्ट्रिंग चाहता है।

अब मैं बाइट ऑर्डर को नेटवर्क बाइट ऑर्डर में बदलता हूं और मुझे निम्नलिखित मिलते हैं:

>>> struct.unpack("!L","")
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
struct.error: unpack requires a string argument of length 4

अचानक यह केवल 8-बाइट लंबे मूल्य के लिए 4 बाइट्स चाहता है।

उस के साथ क्या हो रहा है, और मैं इसे पाने के लिए क्या कर सकता हूं?

उत्तर:

उत्तर № 1 के लिए 1

यहां मुद्दा यह है कि struct अपनी मशीन का मूल उपयोग कर रहा है long पहले मामले में आकार, और struct"मानक" long दूसरे में आकार।

पहले उदाहरण में, आप कोई निर्दिष्ट नहीं करते हैं बाइट-ऑर्डर, आकार और संरेखण विनिर्देशक (में से एक @=<>!) तो struct मान लिया गया है "@", जो आपके मशीन के मूल मूल्यों का उपयोग करता है, अर्थात् आपकी मशीन का मूल long आकार। प्लेटफार्मों के अनुरूप होने के लिए, struct प्रत्येक प्रकार के लिए मानक आकार को परिभाषित करता है, जो आपके मशीन के मूल आकारों से भिन्न हो सकता है "@" इन मानक आकारों का उपयोग करता है।

तो, के मामले में long, struct"मानक 4 बाइट्स है, यही कारण है कि "!L" (या कोई भी "[=<>!]L" 4 बाइट्स की उम्मीद है। हालाँकि, आपकी मशीन देशी है long जाहिरा तौर पर 8 बाइट्स है, यही वजह है "@L" या "L" उम्मीदें 8. यदि आप अपनी मशीन के मूल बाइट-ऑर्डर का उपयोग करना चाहते हैं, लेकिन अभी भी इसके साथ संगत हैं struct"मानक आकार, मैं अनुशंसा करूंगा कि आप सभी स्वरूपों को निर्दिष्ट करें "=", बजाय पायथन को इसे डिफ़ॉल्ट करने के लिए "@".


आप के साथ आकार की उम्मीद की जाँच कर सकते हैं struct.calcsize, अर्थात।:

>>> struct.calcsize("@L"), struct.calcsize("=L")

(यह रिटर्न (4, 4) मेरे 64-बिट विंडोज 10 मशीन पर, लेकिन (8, 4) मेरे 64-बिट Ubuntu 16.04 मशीन पर।)

तुम भी सीधे एक संकलन करके अपने मशीन के प्रकार के आकार की जाँच कर सकते हैं C का मान जाँचने के लिए स्क्रिप्ट sizeof(long), उदाहरण के लिए:

#include <stdio.h>

int main()
{
printf("%li",sizeof(long));
return 0;
}

मैंने पीछा किया यह गाइड संकलन करने के लिए C मेरी विंडोज 10 मशीन पर स्क्रिप्ट।