खैर, यह मिस यूनिवर्स पुरस्कार को जीतने नहीं है, लेकिन मैं इसे आप क्या चाहते हैं करता है लगता है:
#include <boost/preprocessor/cat.hpp>
typedef unsigned char uchar;
typedef unsigned short ushort;
#define PAD_FIELDS(i_,f_, n_) \
typedef struct __attribute__((packed)) {f_} ftype##i_; \
typedef struct __attribute__((packed)) {f_ uchar t_;} ttype##i_; \
f_ uchar BOOST_PP_CAT(padding,i_)[n_ - sizeof (BOOST_PP_CAT(ftype,i_)) * (sizeof (BOOST_PP_CAT(ftype,i_)) != sizeof (BOOST_PP_CAT(ttype,i_)))];
struct sFPGA {
PAD_FIELDS(1,
PAD_FIELDS(2,
uchar Spare1[0x24];
ushort DiscreteInput;
//CPLD_Version is required to be at offset 0xA0
, 0xA0) // First padding
ushort CPLD_Version;
uchar more_stuff[0x50];
ushort even_more[4];
//NID_Version is required to be at offset 0x10A2
, 0x10A2) // Second padding
ushort NID_Version;
} __attribute__((packed));
int main() {
printf("CPLD_Version offset %x\n", offsetof(sFPGA,CPLD_Version));
printf("NID_Version offset %x\n", offsetof(sFPGA,NID_Version));
}
मान लीजिए कि आप चाहते हैं एन = 20 चलो पैडिंग फ़ील्ड आपको अपनी संरचना की शुरुआत में उन PAD_FIELDS(i,
में से एन को जोड़ना होगा, जहां i
उदाहरण के लिए 1 से 20 (मेरे उदाहरण में) या 0 से 1 9 तक या जो भी आपको खुश करता है, के लिए चलता है। फिर, जब आपको पैडिंग की आवश्यकता होती है तो उदाहरण के लिए , 0x80)
जिसका अर्थ है कि अगला फ़ील्ड संरचना की शुरुआत से ऑफसेट 0x80 पर स्थित होगा।
इस कोड चलाने पर, यह निम्न पाठ आउटपुट:
CPLD_Version offset a0
NID_Version offset 10a2
तरह से इस मैक्रो काम करता है यह अपने क्षेत्रों के साथ एक संरचना को परिभाषित करता है, यह तो अपने क्षेत्रों को शामिल किया गया है, और गद्दी के अनुसार गणना की कहते हैं संरचना।
#include <boost/preprocessor/cat.hpp>
#include <boost/preprocessor/comma.hpp>
#include <boost/preprocessor/repetition/repeat.hpp>
#include <boost/preprocessor/punctuation/paren.hpp>
typedef unsigned char uchar;
typedef unsigned short ushort;
#define PAD_FIELDS(i_,f_, n_) \
typedef struct __attribute__((packed)) {f_} BOOST_PP_CAT(ftype,i_); \
typedef struct __attribute__((packed)) {f_ uchar t_;} BOOST_PP_CAT(ttype,i_); \
f_ uchar BOOST_PP_CAT(padding,i_)[n_ - sizeof (BOOST_PP_CAT(ftype,i_)) * (sizeof (BOOST_PP_CAT(ftype,i_)) != sizeof (BOOST_PP_CAT(ttype,i_)))];
#define PADMAC(z,n,s) PAD_FIELDS BOOST_PP_LPAREN() n BOOST_PP_COMMA()
#define PADREP(n) BOOST_PP_REPEAT(n, PADMAC, junk)
#define FORCE_EVAL(...) __VA_ARGS__
#define CONTAINS_PADDING(n) FORCE_EVAL(PADREP(n)
#define SET_OFFSET(o) BOOST_PP_COMMA() o BOOST_PP_RPAREN()
struct sFPGA {
CONTAINS_PADDING(2);
uchar Spare1[0x24];
ushort DiscreteInput;
//CPLD_Version is required to be at offset 0xA0
SET_OFFSET(0xA0);
ushort CPLD_Version;
uchar more_stuff[0x50];
ushort even_more[4];
//NID_Version is required to be at offset 0x10A2
SET_OFFSET(0x10A2);
ushort NID_Version;
)
} __attribute__((packed));
सूचना क्या उपयोग में बदल दिया है::
-
आप कुछ बढ़ावा :: पूर्वप्रक्रमक जादू कोई आपत्ति नहीं है, यहाँ एक तरह से आप पूरी PAD_FIELDS(1,PAD_FIELDS(2,PAD_FIELDS(3,PAD_FIELDS(4,...
शुरुआत में स्वचालित कर सकते हैं है संरचना की शुरुआत में आप CONTAINS_PADDING(n)
लिखते हैं जहां n
वांछित पैडिंग तत्वों की संख्या है।
- संरचना के अंत से ठीक पहले आपको ")" जोड़ना होगा।
,0x0A)
के बजाय SET_OFFSET(0x0A);
(;
वैकल्पिक) लिखने के लिए पैडिंग निर्दिष्ट करने के लिए।
साइड नोट: अतिरिक्त फ़ील्ड्स को आम तौर पर 'आरक्षित 1', 'आरक्षित 2' आदि के रूप में संदर्भित किया जाता है (कम से कम यह वह सम्मेलन है जिसे मैंने हमेशा प्रदर्शित करने के लिए संरचना का उपयोग करते समय कोड में देखा है मेमोरी मैप किए गए रजिस्टर्स)। –
https://en.wikipedia.org/wiki/Data_structure_alignment – fstamour