ในส่วนนี้จะอธิบายประเภทข้อมูล HIDL สำหรับรายละเอียดการใช้งาน โปรดดูที่ HIDL C++ (สำหรับการใช้งาน C++) หรือ HIDL Java (สำหรับการใช้งาน Java)
ความคล้ายคลึงกับ C ++ รวมถึง:
-
structs
ใช้ไวยากรณ์ C ++;unions
สนับสนุนไวยากรณ์ C++ ตามค่าเริ่มต้น จะต้องตั้งชื่อทั้งสอง ไม่รองรับโครงสร้างและสหภาพที่ไม่ระบุชื่อ - อนุญาตให้ใช้ Typedef ใน HIDL (เช่นเดียวกับใน C ++)
- อนุญาตให้ใช้ความคิดเห็นสไตล์ C++ และคัดลอกไปยังไฟล์ส่วนหัวที่สร้างขึ้น
ความคล้ายคลึงกับ Java ได้แก่ :
- สำหรับแต่ละไฟล์ HIDL จะกำหนดเนมสเปซสไตล์ Java ที่ต้องขึ้นต้นด้วย
android.hardware.
. เนมสเปซ C ++ ที่สร้างขึ้นคือ::android::hardware::…
- คำจำกัดความทั้งหมดของไฟล์มีอยู่ภายใน wrapper
interface
สไตล์ Java - การประกาศอาร์เรย์ HIDL เป็นไปตามสไตล์ Java ไม่ใช่สไตล์ C++ ตัวอย่าง:
struct Point { int32_t x; int32_t y; }; Point[3] triangle; // sized array
- ความคิดเห็นจะคล้ายกับรูปแบบ javadoc
การแสดงข้อมูล
struct
หรือ union
ที่ประกอบด้วย เค้าโครงมาตรฐาน (ชุดย่อยของข้อกำหนดของประเภทข้อมูลเก่าธรรมดา) มีเค้าโครงหน่วยความจำที่สอดคล้องกันในโค้ด C++ ที่สร้างขึ้น ซึ่งบังคับใช้ด้วยแอตทริบิวต์การจัดตำแหน่งที่ชัดเจนใน struct
และสมาชิก union
ประเภท HIDL ดั้งเดิม เช่นเดียวกับประเภท enum
และ bitfield
(ซึ่งมักจะมาจากประเภทดั้งเดิม) แมปกับประเภท C++ มาตรฐาน เช่น std::uint32_t
จาก cstdint
เนื่องจาก Java ไม่รองรับประเภทที่ไม่ได้ลงนาม ประเภท HIDL ที่ไม่ได้ลงนามจึงถูกแมปกับประเภท Java ที่ลงนามที่สอดคล้องกัน โครงสร้าง แมปกับคลาส Java; อาร์เรย์ แมปกับอาร์เรย์ Java; ขณะนี้ยังไม่รองรับ สหภาพแรงงาน ใน Java สตริง จะถูกจัดเก็บภายในเป็น UTF8 เนื่องจาก Java รองรับเฉพาะสตริง UTF16 ค่าสตริงที่ส่งไปยังหรือจากการใช้งาน Java จะถูกแปล และอาจไม่เหมือนกันในการแปลใหม่ เนื่องจากชุดอักขระไม่ได้แมปอย่างราบรื่นเสมอไป
ข้อมูลที่ได้รับผ่าน IPC ใน C++ ถูกทำเครื่องหมายว่า const
และอยู่ในหน่วยความจำแบบอ่านอย่างเดียวซึ่งคงอยู่เฉพาะในช่วงระยะเวลาของการเรียกใช้ฟังก์ชันเท่านั้น ข้อมูลที่ได้รับผ่าน IPC ใน Java ได้ถูกคัดลอกไปยังอ็อบเจ็กต์ Java แล้ว ดังนั้นจึงสามารถเก็บรักษาไว้ได้โดยไม่ต้องคัดลอกเพิ่มเติม (และอาจได้รับการแก้ไข)
คำอธิบายประกอบ
คำอธิบายประกอบแบบ Java อาจถูกเพิ่มลงในการประกาศประเภท คำอธิบายประกอบจะถูกแยกวิเคราะห์โดยแบ็กเอนด์ Vendor Test Suite (VTS) ของคอมไพเลอร์ HIDL แต่คอมไพเลอร์ HIDL ไม่เข้าใจคำอธิบายประกอบที่แยกวิเคราะห์ดังกล่าวจริงๆ แต่คำอธิบายประกอบ VTS ที่แยกวิเคราะห์จะถูกจัดการโดย VTS Compiler (VTSC) แทน
คำอธิบายประกอบใช้ไวยากรณ์ Java: @annotation
หรือ @annotation(value)
หรือ @annotation(id=value, id=value…)
โดยที่ value อาจเป็นนิพจน์คงที่ สตริง หรือรายการของค่าภายใน {}
เช่นเดียวกับใน ชวา คุณสามารถแนบคำอธิบายประกอบหลายรายการที่มีชื่อเดียวกันลงในรายการเดียวกันได้
ประกาศไปข้างหน้า
ใน HIDL โครงสร้างไม่สามารถถูกประกาศไปข้างหน้า ซึ่งทำให้ประเภทข้อมูลที่ผู้ใช้กำหนดและอ้างอิงตนเองเป็นไปไม่ได้ (เช่น คุณไม่สามารถอธิบายรายการที่เชื่อมโยงหรือแผนผังใน HIDL) HAL ที่มีอยู่ส่วนใหญ่ (ก่อน Android 8.x) มีการใช้งานการประกาศไปข้างหน้าอย่างจำกัด ซึ่งสามารถลบออกได้โดยการจัดเรียงการประกาศโครงสร้างข้อมูลใหม่
ข้อจำกัดนี้อนุญาตให้คัดลอกโครงสร้างข้อมูลตามค่าด้วยการคัดลอกเชิงลึกอย่างง่าย แทนที่จะติดตามค่าตัวชี้ที่อาจเกิดขึ้นหลายครั้งในโครงสร้างข้อมูลอ้างอิงตัวเอง หากข้อมูลเดียวกันถูกส่งสองครั้ง เช่น ด้วยพารามิเตอร์เมธอดสองตัวหรือ vec<T>
ที่ชี้ไปยังข้อมูลเดียวกัน จะมีการสร้างและจัดส่งสำเนาสองชุดแยกกัน
การประกาศที่ซ้อนกัน
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
- สามารถใช้เป็นชนิดพิเศษในฟิลด์โครงสร้าง/สหภาพ พารามิเตอร์เมธอด และการส่งคืน มันถูกมองว่าเป็นอินเทอร์เฟซทั่วไปและคำพ้องความหมายกับ
android.hidl.base@1.0::IBase
ตัวอย่างเช่น IServiceManager
มีวิธีการดังต่อไปนี้:
get(string fqName, string name) generates (interface service);
วิธีการสัญญาว่าจะค้นหา อินเทอร์เฟซ ตามชื่อ นอกจากนี้ยังเหมือนกับการแทนที่อินเทอร์เฟซด้วย android.hidl.base@1.0::IBase
อินเทอร์เฟซสามารถส่งผ่านได้สองวิธีเท่านั้น: เป็นพารามิเตอร์ระดับบนสุด หรือเป็นสมาชิกของ vec<IMyInterface>
ไม่สามารถเป็นสมาชิกของ vec, structs, array หรือ union ที่ซ้อนกันได้
MQDescriptorSync และ MQDescriptorUnsync
ประเภท MQDescriptorSync
และ MQDescriptorUnsync
จะส่งผ่านตัวอธิบาย Fast Message Queue (FMQ) ที่ซิงโครไนซ์หรือไม่ซิงโครไนซ์ผ่านอินเทอร์เฟซ HIDL สำหรับรายละเอียด โปรดดู HIDL C++ (Java ไม่รองรับ FMQ)
ประเภทหน่วยความจำ
ประเภทหน่วย memory
ใช้เพื่อแสดงหน่วยความจำที่ใช้ร่วมกันที่ไม่ได้แมปใน HIDL รองรับเฉพาะในภาษา C++ เท่านั้น ค่าประเภทนี้สามารถใช้ในส่วนรับเพื่อเริ่มต้นวัตถุ IMemory
การแมปหน่วยความจำ และทำให้สามารถใช้งานได้ สำหรับรายละเอียด โปรดดูที่ HIDL C++
คำเตือน: ข้อมูลที่มีโครงสร้างที่วางอยู่ในหน่วยความจำที่ใช้ร่วมกันต้องเป็นประเภทที่รูปแบบจะไม่เปลี่ยนแปลงตลอดอายุการใช้งานของเวอร์ชันอินเทอร์เฟซที่ส่งผ่าน memory
มิฉะนั้น HAL อาจประสบปัญหาความเข้ากันได้ร้ายแรง
ประเภทตัวชี้
ประเภท pointer
มีไว้สำหรับใช้ภายใน HIDL เท่านั้น
เทมเพลตประเภท bitfield<T>
bitfield<T>
โดยที่ T
เป็น enum ที่ผู้ใช้กำหนด แนะนำว่าค่านั้นเป็น bitwise-OR ของค่า enum ที่กำหนดใน T
ในโค้ดที่สร้างขึ้น 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);
คอมไพเลอร์จัดการประเภท Flags เช่นเดียวกับ uint8_t
ทำไมไม่ใช้ (u)int8_t
/ (u)int16_t
/ (u)int32_t
/ (u)int64_t
? การใช้ bitfield
จะให้ข้อมูล HAL เพิ่มเติมแก่ผู้อ่าน ซึ่งขณะนี้ทราบแล้วว่า setFlags
รับค่าระดับบิตหรือหรือของ Flag (เช่น รู้ว่าการเรียก setFlags
ด้วย 16 นั้นไม่ถูกต้อง) หากไม่มี bitfield
ข้อมูลนี้จะถูกส่งผ่านเอกสารประกอบเท่านั้น นอกจากนี้ VTS ยังสามารถตรวจสอบได้ว่าค่าของแฟล็กเป็นค่าบิตหรือของแฟล็กหรือไม่
จัดการประเภทดั้งเดิม
คำเตือน: ที่อยู่ทุกชนิด (แม้แต่ที่อยู่อุปกรณ์จริง) จะต้องไม่เป็นส่วนหนึ่งของหมายเลขอ้างอิงดั้งเดิม การส่งข้อมูลนี้ระหว่างกระบวนการต่างๆ ถือเป็นอันตรายและทำให้เสี่ยงต่อการถูกโจมตีได้ ค่าใดๆ ที่ส่งผ่านระหว่างกระบวนการจะต้องได้รับการตรวจสอบก่อนจึงจะถูกนำมาใช้เพื่อค้นหาหน่วยความจำที่จัดสรรภายในกระบวนการ มิฉะนั้น หมายเลขอ้างอิงที่ไม่ถูกต้องอาจทำให้การเข้าถึงหน่วยความจำไม่ดีหรือหน่วยความจำเสียหาย
ซีแมนทิกส์ 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
(ทั้งระดับบนสุดหรือส่วนหนึ่งของประเภทผสม) ความเป็นเจ้าของไฟล์ descriptors ที่มีอยู่ในนั้นจะเป็นดังนี้:
- ผู้เรียก ที่ส่งวัตถุ
hidl_handle
เป็นอาร์กิวเมนต์ยังคงรักษาความเป็นเจ้าของตัวอธิบายไฟล์ที่มีอยู่ในnative_handle_t
ที่มันล้อมรอบ ผู้เรียกจะต้องปิดตัวอธิบายไฟล์เหล่านี้เมื่อเสร็จสิ้น - กระบวนการ ส่งคืนอ็อบเจ็กต์
hidl_handle
(โดยส่งผ่านไปยังฟังก์ชัน_cb
) ยังคงความเป็นเจ้าของตัวอธิบายไฟล์ที่มีอยู่ในnative_handle_t
ที่ห่อหุ้มด้วยอ็อบเจ็กต์ กระบวนการจะต้องปิดตัวอธิบายไฟล์เหล่านี้เมื่อเสร็จสิ้น - การขนส่ง ที่ได้รับ
hidl_handle
มีความเป็นเจ้าของตัวอธิบายไฟล์ภายในnative_handle_t
ที่ห่อด้วยอ็อบเจ็กต์ ผู้รับสามารถใช้ตัวอธิบายไฟล์เหล่านี้ตามที่เป็นอยู่ในระหว่างการติดต่อกลับของธุรกรรม แต่ต้องโคลนหมายเลขอ้างอิงดั้งเดิมเพื่อใช้ตัวอธิบายไฟล์นอกเหนือจากการโทรกลับ การขนส่งจะclose()
ตัวอธิบายไฟล์โดยอัตโนมัติเมื่อธุรกรรมเสร็จสิ้น
HIDL ไม่รองรับการจัดการใน Java (เนื่องจาก Java ไม่รองรับการจัดการเลย)
อาร์เรย์ขนาด
สำหรับอาร์เรย์ที่มีขนาดในโครงสร้าง HIDL องค์ประกอบสามารถเป็นประเภทใดก็ได้ที่โครงสร้างสามารถมีได้:
struct foo { uint32_t[3] x; // array is contained in foo };
สตริง
สตริงจะปรากฏแตกต่างกันใน C++ และ Java แต่ประเภทการจัดเก็บข้อมูลการขนส่งที่สำคัญคือโครงสร้าง C++ สำหรับรายละเอียด โปรดดู ประเภทข้อมูล HIDL C++ หรือ ประเภทข้อมูล HIDL Java
หมายเหตุ: การส่งสตริงไปยังหรือจาก Java ผ่านอินเทอร์เฟซ HIDL (รวมถึง 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 อยู่ในรายการนี้ยกเว้นอินเทอร์เฟซ
ประเภทที่ผู้ใช้กำหนด
ส่วนนี้จะอธิบายประเภทที่ผู้ใช้กำหนด
เอนัม
HIDL ไม่รองรับการแจงนับที่ไม่ระบุชื่อ มิฉะนั้น enums ใน HIDL จะคล้ายกับ C++11:
enum name : type { enumerator , enumerator = constexpr , … }
enum ฐานถูกกำหนดในแง่ของหนึ่งในประเภทจำนวนเต็มใน HIDL หากไม่มีการระบุค่าสำหรับตัวแจงนับตัวแรกของการแจงนับตามประเภทจำนวนเต็ม ค่าดีฟอลต์จะเป็น 0 หากไม่มีการระบุค่าสำหรับตัวแจงนับในภายหลัง ค่าดีฟอลต์จะเป็นค่าก่อนหน้าบวกหนึ่ง ตัวอย่างเช่น:
// RED == 0 // BLUE == 4 (GREEN + 1) enum Color : uint32_t { RED, GREEN = 3, BLUE }
enum ยังสามารถสืบทอดจาก enum ที่กำหนดไว้ก่อนหน้านี้ได้ หากไม่มีการระบุค่าสำหรับตัวแจงนับตัวแรกของแจงนับลูก (ในกรณีนี้ FullSpectrumColor
) ค่าดีฟอลต์จะถูกระบุเป็นค่าของตัวแจงนับตัวสุดท้ายของแจงนับพาเรนต์บวกหนึ่ง ตัวอย่างเช่น:
// ULTRAVIOLET == 5 (Color:BLUE + 1) enum FullSpectrumColor : Color { ULTRAVIOLET }
คำเตือน: การสืบทอด Enum ทำงานแบบย้อนกลับจากการสืบทอดประเภทอื่นๆ ส่วนใหญ่ ค่าแจงนับลูกไม่สามารถใช้เป็นค่าแจงนับพาเรนต์ได้ เนื่องจากแจงนับลูกมีค่ามากกว่าค่าพาเรนต์ อย่างไรก็ตาม ค่าแจงนับพาเรนต์สามารถใช้เป็นค่าแจงนับย่อยได้อย่างปลอดภัย เนื่องจากค่าแจงนับย่อยคือค่าซูเปอร์เซ็ตของค่าแจงนับพาเรนต์ตามคำนิยาม โปรดคำนึงถึงสิ่งนี้เมื่อออกแบบอินเทอร์เฟซ เนื่องจากหมายความว่าประเภทที่อ้างถึงการแจงนับพาเรนต์จะไม่สามารถอ้างถึงแจงย่อยย่อยในการวนซ้ำอินเทอร์เฟซของคุณในภายหลัง
ค่าของแจงนับจะอ้างอิงตามไวยากรณ์โคลอน (ไม่ใช่ไวยากรณ์จุดเป็นประเภทที่ซ้อนกัน) ไวยากรณ์คือ 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 enums มีแอตทริบิวต์ len
ที่สามารถใช้ในนิพจน์คงที่ได้ MyEnum::len
คือจำนวนรายการทั้งหมดในการแจงนับนั้น ซึ่งแตกต่างจากจำนวนค่าทั้งหมดซึ่งอาจน้อยกว่าเมื่อมีการทำซ้ำค่า
โครงสร้าง
HIDL ไม่รองรับโครงสร้างที่ไม่ระบุชื่อ มิฉะนั้น โครงสร้างใน HIDL จะคล้ายกับ C มาก
HIDL ไม่รองรับโครงสร้างข้อมูลที่มีความยาวผันแปรได้ซึ่งอยู่ภายในโครงสร้างทั้งหมด ซึ่งรวมถึงอาร์เรย์ที่มีความยาวไม่จำกัดซึ่งบางครั้งใช้เป็นฟิลด์สุดท้ายของโครงสร้างใน C/C++ (บางครั้งเห็นด้วยขนาด [0]
) HIDL vec<T>
แสดงถึงอาร์เรย์ขนาดไดนามิกพร้อมข้อมูลที่จัดเก็บไว้ในบัฟเฟอร์แยกต่างหาก กรณีดังกล่าวจะแสดงด้วยอินสแตนซ์ของ vec<T>
ใน struct
ในทำนองเดียวกัน string
สามารถอยู่ใน struct
ได้ (บัฟเฟอร์ที่เกี่ยวข้องจะแยกจากกัน) ใน C ++ ที่สร้างขึ้น อินสแตนซ์ของประเภทตัวจัดการ HIDL จะแสดงผ่านตัวชี้ไปยังตัวจัดการดั้งเดิมจริง เนื่องจากอินสแตนซ์ของชนิดข้อมูลพื้นฐานมีความยาวผันแปรได้
ยูเนี่ยน
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 }