এই বিভাগে HIDL ডেটার ধরন বর্ণনা করা হয়েছে। প্রয়োগ করার বিবরণ জানতে, HIDL C++ (C++ প্রয়োগের জন্য) অথবা HIDL Java (Java প্রয়োগের জন্য) দেখুন।
C++-এর সাথে মিলের মধ্যে এগুলি অন্তর্ভুক্ত:
structsC++ সিনট্যাক্স ব্যবহার করে;unionsডিফল্ট হিসেবে C++ সিনট্যাক্স সাপোর্ট করে। দুটিকেই নাম দিতে হবে; বেনামী স্ট্রাকচার ও ইউনিয়ন কাজ করে না।- HIDL-এ Typedef-এর অনুমতি আছে (C++-এ যেমন আছে)।
- C++-স্টাইলের কমেন্ট করার অনুমতি আছে এবং এটি জেনারেট করা হেডার ফাইলে কপি করা হয়।
Java-এর সাথে মিলের মধ্যে অন্তর্ভুক্ত হল:
- প্রতিটি ফাইলের জন্য, HIDL একটি জাভা-স্টাইল নেমস্পেস সংজ্ঞায়িত করে যা অবশ্যই শুরু হতে হবে
android.hardware.. জেনারেট করা C++ নেমস্পেস হল::android::hardware::…। - ফাইলের সব সংজ্ঞা Java-স্টাইলের
interfaceর্যাপারের মধ্যে থাকে। - HIDL অ্যারে ঘোষণা Java স্টাইল মেনে চলে, C++ স্টাইল নয়। উদাহরণ:
struct Point { int32_t x; int32_t y; }; Point[3] triangle; // sized array - কমেন্টগুলি javadoc ফর্ম্যাটের মতো।
ডেটা রিপ্রেজেন্টেশন
struct বা union যা
Standard-Layout
(প্লেইন-ওল্ড-ডেটা টাইপের প্রয়োজনীয়তার সাবসেট) দিয়ে তৈরি, সেটির জেনারেট করা C++ কোডে একটি কনসিস্টেন্ট মেমরি
লেআউট থাকে, যা struct ও union মেম্বারে এক্সপ্লিসিট অ্যালাইনমেন্ট অ্যাট্রিবিউটের মাধ্যমে
এনফোর্স করা হয়।
প্রিমিটিভ HIDL ধরনের পাশাপাশি enum ও bitfield
ধরনের (যা সবসময় প্রিমিটিভ ধরন থেকে পাওয়া যায়) ম্যাপ স্ট্যান্ডার্ড C++ ধরনের
যেমন cstdint থেকে
std::uint32_t।
যেহেতু Java আনসাইন করা ধরন সাপোর্ট করে না, তাই আনসাইন করা HIDL ধরনকে সংশ্লিষ্ট সাইন করা Java ধরনের সাথে ম্যাপ করা হয়। Structs জাভা ক্লাসে ম্যাপ করে; arrays জাভা অ্যারেতে ম্যাপ করে; unions বর্তমানে জাভাতে কাজ করে না। স্ট্রিং ইন্টার্নালি UTF8 হিসেবে স্টোর করা হয়। Java-তে শুধু UTF16 স্ট্রিং কাজ করে বলে, Java ইমপ্লিমেন্টেশনে পাঠানো বা সেখান থেকে পাওয়া স্ট্রিং ভ্যালু অনুবাদ করা হয় এবং অক্ষর সেট সবসময় সঠিকভাবে ম্যাপ করা যায় না বলে, আবার অনুবাদ করা হলে তা একই নাও হতে পারে।
C++-এ IPC-এর মাধ্যমে পাওয়া ডেটা const হিসেবে চিহ্নিত করা হয় এবং এটি
রিড-অনলি মেমরিতে থাকে যা ফাংশন কল চলাকালীনই শুধু থাকে। জাভাতে IPC-এর মাধ্যমে পাওয়া ডেটা
আগে থেকেই জাভা অবজেক্টে কপি করা হয়েছে, তাই অতিরিক্ত কপি না করেই
সেটি রেখে দেওয়া যাবে (এবং পরিবর্তন করা যাবে)।
টিকা
টাইপ ডিক্লারেশনে জাভা-স্টাইল অ্যানোটেশন যোগ করা যেতে পারে। HIDL কম্পাইলারের ভেন্ডর টেস্ট স্যুট (VTS) ব্যাকএন্ডের মাধ্যমে অ্যানোটেশন পার্স করা হয়, কিন্তু এই ধরনের পার্স করা অ্যানোটেশনের কোনওটিই HIDL কম্পাইলার আসলে বুঝতে পারে না। পরিবর্তে, পার্স করা VTS অ্যানোটেশন VTS কম্পাইলার (VTSC) দ্বারা ম্যানেজ করা হয়।
অ্যানোটেশনে Java সিনট্যাক্স ব্যবহার করা হয়: @annotation বা
@annotation(value) বা @annotation(id=value, id=value…)
যেখানে ভ্যালু, Java-এর মতো {}-এর মধ্যে
কনস্ট্যান্ট এক্সপ্রেশন, স্ট্রিং বা ভ্যালুর তালিকা হতে পারে। একই নামের একাধিক অ্যানোটেশন
একই আইটেমের সাথে অ্যাটাচ করা যেতে পারে।
ফরওয়ার্ড ডিক্লারেশন
HIDL-এ, স্ট্রাক্ট আগে থেকে ঘোষণা করা নাও হতে পারে, এর ফলে ব্যবহারকারীর সংজ্ঞায়িত, সেল্ফ-রেফারেন্সিয়াল ডেটা টাইপ অসম্ভব হয়ে যায় (যেমন, আপনি HIDL-এ লিঙ্ক করা তালিকা বা ট্রি বর্ণনা করতে পারবেন না)। আগে থেকে থাকা (Android 8.x-এর আগের ভার্সন) বেশিরভাগ HAL-এ ফরোয়ার্ড ডিক্লারেশনের সীমিত ব্যবহার আছে, যা ডেটা স্ট্রাকচার ডিক্লারেশন রিঅ্যারেঞ্জ করার মাধ্যমে সরানো যেতে পারে।
এই বিধিনিষেধের ফলে, ডেটা স্ট্রাকচারকে একটি সাধারণ
ডিপ-কপি সহ ভ্যালু-দ্বারা কপি করা যায়, তার পরিবর্তে পয়েন্টার ভ্যালু ট্র্যাক করা হয় না যা সেল্ফ-রেফারেন্সিয়াল ডেটা স্ট্রাকচারে একাধিক
বার ঘটতে পারে। একই ডেটা দু'বার পাস করা হলে,
যেমন দুটি মেথড প্যারামিটার বা vec<T>s যা একই ডেটার
দিকে পয়েন্ট করে, দুটি আলাদা কপি তৈরি করে ডেলিভার করা হয়।
নেস্ট করা ডিক্লারেশন
HIDL-এ যত লেভেল প্রয়োজন তত লেভেলের নেস্টেড ডিক্লারেশন কাজ করে (নিচে উল্লেখ করা একটি ব্যতিক্রম সহ)। যেমন:
interface IFoo { uint32_t[3][4][5][6] multidimArray; vec<vec<vec<int8_t>>> multidimVector; vec<bool[4]> arrayVec; struct foo { struct bar { uint32_t val; }; bar b; } struct baz { foo f; foo.bar fb; // HIDL uses dots to access nested type names } …
এর ব্যতিক্রম হল, ইন্টারফেসের ধরন শুধুমাত্র
vec<T>-এ এম্বেড করা যায় এবং সেটি শুধুমাত্র এক লেভেল গভীর হতে পারে (কোনও
vec<vec<IFoo>> নয়)।
র পয়েন্টারের সিনট্যাক্স
HIDL ভাষা * ব্যবহার করে না এবং C/C++ র' পয়েন্টারের সম্পূর্ণ নমনীয়তা সমর্থন করে না। HIDL কীভাবে পয়েন্টার ও অ্যারে/ভেক্টর এনক্যাপসুলেট করে সেই ব্যাপারে বিস্তারিত জানতে, vec<T> টেমপ্লেট দেখুন।
ইন্টারফেস
interface কীওয়ার্ডটি দুটি অর্থে ব্যবহৃত হয়।
- এটি .hal ফাইলে ইন্টারফেসের সংজ্ঞা খোলে।
- এটি struct/union ফিল্ড, মেথড প্যারামিটার ও রিটার্নে বিশেষ ধরনের ডেটা হিসেবে ব্যবহার করা যেতে পারে। এটি একটি সাধারণ ইন্টারফেস হিসেবে বিবেচিত হয় এবং
android.hidl.base@1.0::IBase-এর সমার্থক।
যেমন, IServiceManager-এর নিম্নলিখিত পদ্ধতি আছে:
get(string fqName, string name) generates (interface service);
এই পদ্ধতিতে নামের মাধ্যমে কিছু ইন্টারফেস লুক-আপ করার প্রতিশ্রুতি দেওয়া হয়। এছাড়াও,
android.hidl.base@1.0::IBase-এর সাথে ইন্টারফেস পরিবর্তন করার মতো একই।
ইন্টারফেস শুধুমাত্র দুটি উপায়ে পাস করা যেতে পারে: টপ-লেভেল প্যারামিটার হিসেবে অথবা
vec<IMyInterface>-এর মেম্বার হিসেবে। এগুলি নেস্টেড ভেক্টর, স্ট্রাকচার, অ্যারে বা ইউনিয়নের মেম্বার হতে পারে না।
MQDescriptorSync and MQDescriptorUnsync
MQDescriptorSync ও MQDescriptorUnsync ধরনের
সিঙ্ক্রোনাইজড বা আনসিঙ্ক্রোনাইজড ফাস্ট মেসেজ কিউ (FMQ) ডেসক্রিপ্টর
HIDL ইন্টারফেসের মাধ্যমে পাস করে। বিস্তারিত জানতে, HIDL C++ দেখুন (FMQ Java-তে
কাজ করে না)।
মেমোরির ধরন
HIDL-এ আনম্যাপ করা শেয়ারড মেমরিকে দেখানোর জন্য memory ধরন ব্যবহার করা হয়।
এটি শুধুমাত্র C++-এ কাজ করে। এই ধরনের ভ্যালু IMemory অবজেক্ট ইনিশিয়ালাইজ করার জন্য
প্রাপক প্রান্তে ব্যবহার করা যেতে পারে, মেমরি ম্যাপ করে
সেটিকে ব্যবহারযোগ্য করে তোলে। আরও বিবরণের জন্য, HIDL C++ দেখুন।
সতর্কতা: শেয়ার করা মেমরিতে প্লেস করা স্ট্রাকচার্ড ডেটা
অবশ্যই এমন ধরনের হতে হবে যার ফর্ম্যাট memory পাস করা ইন্টারফেস ভার্সনের
লাইফটাইম ধরে কখনও পরিবর্তন হয় না। অন্যথায়, HAL-এ
মারাত্মক সামঞ্জস্য সংক্রান্ত সমস্যা হতে পারে।
পয়েন্টারের ধরন
pointer ধরনটি শুধুমাত্র HIDL ইন্টার্নাল ব্যবহারের জন্য।
bitfield<T> টাইপ টেমপ্লেট
bitfield<T> যেখানে T হল একটি
ব্যবহারকারীর-নির্ধারিত enum, এটি সাজেস্ট করে যে মানটি হল T-এ নির্ধারিত enum মানের
বিটওয়াইজ-OR। জেনারেট করা কোডে,
bitfield<T>, T-এর অন্তর্নিহিত টাইপ হিসেবে দেখা যায়। যেমন:
enum Flag : uint8_t { HAS_FOO = 1 << 0, HAS_BAR = 1 << 1, HAS_BAZ = 1 << 2 }; typedef bitfield<Flag> Flags; setFlags(Flags flags) generates (bool success);
কম্পাইলার, uint8_t-এর মতো একই ধরনের Flags হ্যান্ডেল করে।
(u)int8_t/(u)int16_t/(u)int32_t/(u)int64_t
ব্যবহার করা হচ্ছে না কেন?
bitfield ব্যবহার করলে রিডার অতিরিক্ত HAL তথ্য পান,
যিনি এখন জানেন যে setFlags ফ্ল্যাগের বিটওয়াইজ-OR ভ্যালু নেয় (অর্থাৎ,
জানেন যে ১৬ সহ setFlags কল করা ভুল)। bitfield
ছাড়াই, এই তথ্য শুধুমাত্র ডকুমেন্টেশনের মাধ্যমে জানানো হয়। এছাড়াও, VTS আসলে চেক করতে পারে যে ফ্ল্যাগের ভ্যালু Flag-এর বিটওয়াইজ-OR কিনা।
প্রিমিটিভ টাইপ হ্যান্ডেল
সতর্কতা: কোনও ধরনের ঠিকানা (এমনকি ফিজিক্যাল ডিভাইস অ্যাড্রেস) কখনই নেটিভ হ্যান্ডেলের অংশ হতে পারবে না। প্রসেসের মধ্যে এই তথ্য পাস করা বিপজ্জনক এবং এর ফলে সেগুলি অ্যাটাকের শিকার হতে পারে। প্রসেসের মধ্যে পাস করা যেকোনও ভ্যালু, কোনও প্রসেসের মধ্যে বরাদ্দ করা মেমরি লুক-আপ করার জন্য ব্যবহার করার আগে অবশ্যই যাচাই করতে হবে। অন্যথায়, খারাপ হ্যান্ডেল খারাপ মেমরি অ্যাক্সেস বা মেমরি দুর্নীতির কারণ হতে পারে।
HIDL সিম্যান্টিক্স হল কপি-বাই-ভ্যালু, এর অর্থ হল প্যারামিটার কপি করা হয়।
প্রসেসের মধ্যে শেয়ার করতে হবে এমন যেকোনও বড় ডেটা বা ডেটা
(যেমন সিঙ্ক করার জন্য ব্যবহৃত ফেঞ্চ) ফাইল ডেসক্রিপ্টর পাস করার মাধ্যমে ম্যানেজ করা হয়। এই ফাইল ডেসক্রিপ্টর
পারসিস্টেন্ট অবজেক্টের দিকে পয়েন্ট করে: শেয়ার করা মেমরি, আসল ফাইল বা
ফাইল ডেসক্রিপ্টরের পিছনে লুকানো থাকতে পারে এমন যেকোনও কিছুর জন্য ashmem। বাইন্ডার ড্রাইভার
অন্য প্রসেসে ফাইল ডেসক্রিপ্টর ডুপ্লিকেট করে।
native_handle_t
Android-এ native_handle_t কাজ করে, এটি libcutils-এ
সংজ্ঞায়িত একটি সাধারণ হ্যান্ডেল কনসেপ্ট।
typedef struct native_handle { int version; /* sizeof(native_handle_t) */ int numFds; /* number of file-descriptors at &data[0] */ int numInts; /* number of ints at &data[numFds] */ int data[0]; /* numFds + numInts ints */ } native_handle_t;
নেটিভ হ্যান্ডেল হল ints ও ফাইল ডেসক্রিপ্টরের একটি সংগ্রহ যা ভ্যালু দ্বারা
আশেপাশে পাস করা হয়। একটি ফাইল ডেসক্রিপ্টরকে কোনও ints এবং একটি ফাইল ডেসক্রিপ্টর
না থাকা নেটিভ হ্যান্ডেলে স্টোর করা যেতে পারে। handleপ্রিমিটিভ টাইপের সাথে এনক্যাপসুলেট করা নেটিভ হ্যান্ডেল ব্যবহার করে হ্যান্ডেল পাস করা
নিশ্চিত করে যে নেটিভ
হ্যান্ডেল সরাসরি HIDL-এ অন্তর্ভুক্ত করা হয়েছে।
native_handle_t-এর সাইজ পরিবর্তনশীল হওয়ায়, এটি সরাসরি
স্ট্রাক্টে অন্তর্ভুক্ত করা যাবে না। হ্যান্ডেল ফিল্ড আলাদাভাবে
অ্যালোকেট করা native_handle_t-এর দিকে পয়েন্টার জেনারেট করে।
Android-এর আগের ভার্সনে, নেটিভ হ্যান্ডেলগুলি
libcutils-এ থাকা একই
ফাংশন ব্যবহার করে তৈরি করা হত।
Android 8.0 ও তার পরবর্তী যেকোনও ভার্সনে, এইসব ফাংশন এখন
android::hardware::hidl নেমস্পেসে কপি করা হয় অথবা NDK-তে সরানো হয়। HIDL
অটোজেনারেটেড কোড ব্যবহারকারীর লেখা কোডের সাহায্য ছাড়াই
এইসব ফাংশন অটোমেটিক সিরিয়ালাইজ ও ডিসিরিয়ালাইজ করে।
হ্যান্ডেল ও ফাইল ডেসক্রিপটরের মালিকানা
আপনি যখন কোনও HIDL ইন্টারফেস মেথড কল করেন যা একটি
hidl_handle অবজেক্ট (টপ-লেভেল বা কম্পাউন্ড টাইপের অংশ) পাস (বা রিটার্ন) করে,
এতে থাকা ফাইল ডেসক্রিপটরের মালিকানা নিম্নলিখিতভাবে নির্ধারিত হয়:
- কলার
hidl_handleঅবজেক্টকে আর্গুমেন্ট হিসেবে পাস করলে, এটি যেnative_handle_t-কে র্যাপ করে তার মধ্যে থাকা ফাইল ডেসক্রিপ্টরের মালিকানা ধরে রাখে; কলারকে এই ফাইল ডেসক্রিপ্টরগুলির কাজ হয়ে গেলে সেগুলি বন্ধ করে দিতে হবে। - প্রসেস একটি
hidl_handleঅবজেক্ট ফিরিয়ে দেয় (এটি একটি_cbফাংশনে পাস করার মাধ্যমে) যা অবজেক্ট দ্বারা র্যাপ করাnative_handle_t-এ থাকা ফাইল ডেসক্রিপটরের মালিকানা ধরে রাখে; প্রসেসটি শেষ হয়ে গেলে অবশ্যই এইসব ফাইল ডেসক্রিপটর বন্ধ করতে হবে। - ট্রান্সপোর্ট
hidl_handleপেলে, সেটির কাছে অবজেক্টের মধ্যেnative_handle_tর্যাপ করা ফাইল ডেসক্রিপ্টরের মালিকানা থাকে; ট্রানজ্যাকশন কলব্যাকের সময় রিসিভার এই ফাইল ডেসক্রিপ্টরগুলি যেমন আছে তেমন ব্যবহার করতে পারে, কিন্তু কলব্যাকের পরে ফাইল ডেসক্রিপ্টর ব্যবহার করতে হলে নেটিভ হ্যান্ডেল ক্লোন করতে হবে। ট্রানজ্যাকশন সম্পূর্ণ হয়ে গেলে ট্রান্সপোর্ট অটোমেটিকclose()ফাইল ডেসক্রিপ্টরের জন্য কল করে।
HIDL-এ Java-তে হ্যান্ডেল কাজ করে না (কারণ Java-তে কোনও হ্যান্ডেলই কাজ করে না)।
সাইজ করা অ্যারে
HIDL স্ট্রাকচারে সাইজ করা অ্যারের জন্য, সেগুলির এলিমেন্ট যেকোনও ধরনের হতে পারে যা struct -এ থাকতে পারে:
struct foo {
uint32_t[3] x; // array is contained in foo
};স্ট্রিং
C++ ও Java-তে স্ট্রিং আলাদা আলাদাভাবে দেখা যায়, কিন্তু অন্তর্নিহিত ট্রান্সপোর্ট স্টোরেজ টাইপ হল একটি C++ স্ট্রাকচার। বিস্তারিত জানতে, HIDL C++ ডেটা টাইপ অথবা HIDL Java ডেটা টাইপ দেখুন।
মনে রাখবেন: HIDL ইন্টারফেসের (Java থেকে Java সহ) মাধ্যমে Java-তে বা Java থেকে কোনও স্ট্রিং পাস করলে, ক্যারেক্টার সেট কনভার্সন হয় যা আসল এনকোডিং নাও বজায় রাখতে পারে।
vec<T> টাইপ টেমপ্লেট
vec<T> টেমপ্লেটটি T-এর ইনস্ট্যান্স সহ
পরিবর্তনযোগ্য সাইজের বাফারকে বোঝায়।
T নিম্নলিখিতগুলির মধ্যে একটি হতে পারে:
- প্রিমিটিভ ধরন (যেমন, uint32_t)
- স্ট্রিং
- ব্যবহারকারীর নির্ধারণ করা এনাম
- ব্যবহারকারীর সংজ্ঞায়িত স্ট্রাকচার
- ইন্টারফেস বা
interfaceকীওয়ার্ড (vec<IFoo>,vec<interface>শুধুমাত্র টপ-লেভেল প্যারামিটার হিসেবে কাজ করে ) - হ্যান্ডেল
- <U>বিটফিল্ড
- vec<U>, যেখানে U হল ইন্টারফেস ছাড়া এই তালিকার কোনও একটি (যেমন,
vec<vec<IFoo>>কাজ করে না) - U[] (U-এর সাইজ করা অ্যারে), যেখানে ইন্টারফেস ছাড়া এই তালিকায় U আছে
ব্যবহারকারীর উল্লেখ করা ধরন
এই বিভাগে ব্যবহারকারীর-নির্ধারিত প্রকার বর্ণনা করা হয়েছে।
Enum
HIDL-এ বেনামী এনাম কাজ করে না। অন্যথায়, HIDL-এর এনুমগুলি C++11-এর মতোই হয়:
enum name : type { enumerator , enumerator = constexpr , … }
HIDL-এ একটি পূর্ণসংখ্যা ধরনের ভিত্তিতে একটি বেস এনুম সংজ্ঞায়িত করা হয়। ইনটিজার টাইপের উপর ভিত্তি করে কোনও এনামের প্রথম এনিউমেরেটরের জন্য কোনও ভ্যালু নির্দিষ্ট করা না থাকলে, ডিফল্ট ভ্যালু ০ হয়। পরবর্তী এনুমারেটরের জন্য কোনও ভ্যালু নির্দিষ্ট করা না থাকলে, ভ্যালু ডিফল্ট হিসেবে আগের ভ্যালুর সাথে এক যোগ করা হয়। যেমন:
// RED == 0 // BLUE == 4 (GREEN + 1) enum Color : uint32_t { RED, GREEN = 3, BLUE }
এছাড়াও, কোনও এনুম আগে থেকে সংজ্ঞায়িত এনুম থেকে ইনহেরিট করতে পারে। চাইল্ড এনামের প্রথম এনিউমেরেটরের (এই ক্ষেত্রে
FullSpectrumColor) জন্য কোনও ভ্যালু নির্দিষ্ট করা না থাকলে, এটি ডিফল্ট হিসেবে প্যারেন্ট এনামের শেষ
এনিউমেরেটরের ভ্যালুর সাথে এক যোগ করে নেয়। যেমন:
// ULTRAVIOLET == 5 (Color:BLUE + 1) enum FullSpectrumColor : Color { ULTRAVIOLET }
সতর্কতা: এনুম ইনহেরিটেন্স বেশিরভাগ অন্যান্য ধরনের ইনহেরিটেন্সের থেকে উল্টো দিকে কাজ করে। চাইল্ড এনুম ভ্যালুকে প্যারেন্ট এনুম ভ্যালু হিসেবে ব্যবহার করা যাবে না। এর কারণ হল চাইল্ড এনামে পেরেন্টের থেকে বেশি ভ্যালু থাকে। তবে, প্যারেন্ট এনুম ভ্যালুকে নিরাপদে চাইল্ড এনুম ভ্যালু হিসেবে ব্যবহার করা যেতে পারে কারণ চাইল্ড এনুম ভ্যালু, সংজ্ঞা অনুযায়ী প্যারেন্ট এনুম ভ্যালুর সুপারসেট। ইন্টারফেস ডিজাইন করার সময় এটি মনে রাখবেন, কারণ এর অর্থ হল পেরেন্ট এনামকে রেফার করা টাইপগুলি আপনার ইন্টারফেসের পরবর্তী ইটারেশনে চাইল্ড এনামকে রেফার করতে পারবে না।
এনিমের ভ্যালু কোলন সিনট্যাক্স (নেস্টেড টাইপের মতো ডট সিনট্যাক্স নয়) দিয়ে উল্লেখ করা হয়। সিনট্যাক্স হল Type:VALUE_NAME। ভ্যালু একই এনুমের ধরন বা চাইল্ড ধরনের মধ্যে রেফারেন্স করা হলে
ধরনের উল্লেখ করার প্রয়োজন নেই। উদাহরণ:
enum Grayscale : uint32_t { BLACK = 0, WHITE = BLACK + 1 }; enum Color : Grayscale { RED = WHITE + 1 }; enum Unrelated : uint32_t { FOO = Color:RED + 1 };
Android 10 থেকে শুরু করে, এনামে একটি
len অ্যাট্রিবিউট আছে যা কনস্ট্যান্ট এক্সপ্রেশনে ব্যবহার করা যেতে পারে।
MyEnum::len হল সেই এনুমেরেশনে এন্ট্রিগুলির মোট সংখ্যা।
এটি মোট ভ্যালুর সংখ্যা থেকে আলাদা, যা ভ্যালু ডুপ্লিকেট করা হলে
ছোট হতে পারে।
Struct
HIDL-এ বেনামী স্ট্রাকচার কাজ করে না। অন্যথায়, HIDL-এর স্ট্রাকচারগুলি C-এর সাথে খুব একই রকম।
HIDL-এ ভেরিয়েবল-লেংথ ডেটা স্ট্রাকচার কাজ করে না যা সম্পূর্ণভাবে
একটি স্ট্রাকচারের মধ্যে থাকে। এর মধ্যে রয়েছে অনির্দিষ্ট দৈর্ঘ্যের অ্যারে যা কখনও কখনও C/C++-এ স্ট্রাকচারের শেষ ফিল্ড হিসেবে ব্যবহৃত হয় (কখনও কখনও [0] সাইজের সাথে দেখা যায়)। HIDL vec<T> ডায়নামিক সাইজের অ্যারে দেখায় যার ডেটা আলাদা বাফারে সেভ করা থাকে; এই ধরনের ইনস্ট্যান্সকে struct-এ vec<T>-এর ইনস্ট্যান্স দিয়ে দেখানো হয়।
একইভাবে, struct-এ string থাকতে পারে
(সংশ্লিষ্ট বাফার আলাদা)। জেনারেট করা C++-এ, HIDL
হ্যান্ডেল টাইপের ইনস্ট্যান্সকে আসল নেটিভ হ্যান্ডেলের পয়েন্টার হিসেবে দেখানো হয়, কারণ
আন্ডারলায়িং ডেটা টাইপের ইনস্ট্যান্সের দৈর্ঘ্য পরিবর্তনযোগ্য হয়।
Union
HIDL-এ বেনামী ইউনিয়ন কাজ করে না। অন্যথায়, ইউনিয়নগুলি C-এর মতো।
ইউনিয়নে ফিক্স-আপের ধরন (যেমন, পয়েন্টার, ফাইল ডেসক্রিপ্টর, বাইন্ডার
অবজেক্ট) থাকলে চলবে না। এগুলির জন্য বিশেষ ফিল্ড বা সংশ্লিষ্ট ধরনের প্রয়োজন হয় না এবং memcpy() বা সমতুল্য ব্যবহার করে এগুলি
সহজেই কপি করা যায়। একটি ইউনিয়নে সরাসরি (বা অন্যান্য ডেটা স্ট্রাকচার ব্যবহার করে) এমন কিছু নাও থাকতে পারে যার জন্য বাইন্ডার অফসেট (অর্থাৎ, হ্যান্ডেল বা বাইন্ডার-ইন্টারফেস রেফারেন্স) সেট করতে হয়। যেমন:
union UnionType { uint32_t a; // vec<uint32_t> r; // Error: can't contain a vec<T> uint8_t b;1 }; fun8(UnionType info); // Legal
স্ট্রাক্টের মধ্যেও ইউনিয়ন ঘোষণা করা যেতে পারে। যেমন:
struct MyStruct { union MyUnion { uint32_t a; uint8_t b; }; // declares type but not member union MyUnion2 { uint32_t a; uint8_t b; } data; // declares type but not member }