Serikat RPC

Serikat yang dienkapsulasi dan tidak dienkapsulasi berbagi format union_arm_selector<> umum:

union_arms<2>
arm1_case_value<4> offset_to_arm_description<2>
..
armN_case_value<4> offset_to_arm_description<2>
default_arm_description<2>

Bidang union_arms<2> terdiri dari dua bagian. Jika penyatuan adalah serikat gaya MIDL 1.0, 4 bit atas berisi perataan lengan union (perataan lengan selaras terbesar). Jika tidak, 4 bit atas adalah nol. 12 bit yang lebih rendah berisi jumlah lengan dalam serikat. Dengan kata lain:

alignment<highest nibble> arm_counter<three lower nibbles>

Bidang offset_to_arm_description<2> berisi offset yang ditandatangani relatif ke deskripsi jenis lengan. Namun, bidang kelebihan beban dengan pengoptimalan untuk jenis sederhana. Untuk ini, byte atas bidang offset ini FC_MAGIC_UNION_BYTE (0x80) dan byte yang lebih rendah dari pendek adalah jenis karakter format lengan yang sebenarnya. Dengan demikian, ada dua rentang untuk nilai offset: "80 xx" berarti bahwa xx adalah string format jenis; dan segala sesuatu yang lain dalam rentang (80 FF .. 7f FF) berarti offset aktual. Ini membuat offset dari rentang <80 00 .. 80 FF > tidak tersedia sebagai offset. Pengkompilasi memeriksa bahwa pada MIDL versi 5.1.164.

Bidang default_arm_description<2> menunjukkan jenis lengan serikat untuk lengan default, jika ada. Jika tidak ada lengan default yang ditentukan untuk union, bidang default_arm_description<2> 0xFFFF dan pengecualian dimunculkan jika nilai switch_is tidak cocok dengan salah satu nilai kasus arm. Jika lengan default ditentukan tetapi kosong, maka bidang default_arm_description<2> adalah nol. Jika tidak, bidang default_arm_description<2> memiliki semantik yang sama dengan bidang offset_to_arm_description<2> .

Berikut ini adalah ringkasan:

  • 0 - default kosong
  • FFFF - tidak ada default
  • 80xx - jenis sederhana
  • lainnya - offset relatif

Serikat Terenkapsulasi

Penyatuan yang dienkapsulasi berasal dari sintaks penyatuan khusus dalam IDL. Secara efektif, serikat terenkapsulasi adalah struktur bundel dengan bidang diskriminan di awal struktur dan penyatuan sebagai satu-satunya anggota lainnya.

FC_ENCAPSULATED_UNION switch_type<1> 
memory_size<2>
union_arm_selector<>

Bidang switch_type<1> serikat terenkapmulasi memiliki dua bagian. Nibble yang lebih rendah menyediakan jenis sakelar aktual, dan nibble atas memberikan kenaikan memori untuk melangkahi itu adalah jumlah yang harus ditambahkan penunjuk memori untuk melewati bidang switch_is, yang mencakup setiap padding antara bidang switch_is() dari struktur yang dibangun stub dan bidang penyatuan aktual.

Bidang memory_size<2> adalah ukuran serikat saja, dan identik dengan serikat yang tidak dienkapsulasi. Untuk mendapatkan ukuran total struktur yang berisi penyatuan, tambahkan memory_size<2> ke tahapan memori untuk melangkahi, yaitu ke nibble atas bidang switch_type<1> , lalu selaraskan dengan perataan yang sesuai dengan kenaikan.

Serikat Tidak Terenkapulatasi

Gabungan yang tidak dienkapsulasi adalah situasi umum di mana gabungan adalah satu argumen atau bidang dan sakelar adalah argumen atau bidang lain, masing-masing.

FC_NON_ENCAPSULATED_UNION switch_type<1> 
switch_is_description<>
offset_to_size_and_arm_description<2>

Di mana:

Bidang switch_type<1> adalah karakter format untuk diskriminan.

Bidang switch_is_descriptor<> adalah deskriptor korelasi dan memiliki 4 atau 6 byte tergantung pada apakah /robust digunakan. Namun, untuk switch_is_description<>, jika serikat disematkan dalam struktur, bidang offset switch_is_description<> adalah offset ke bidang switch_is dari posisi serikat dalam struktur (bukan dari awal struktur).

Bidang offset_to_size_and_arm_description<2> memberikan offset ke ukuran serikat dan deskripsi lengan, yang identik dengan itu untuk serikat yang dienkapsulasi dan dibagikan oleh semua serikat yang tidak dienkapsulasi dengan jenis yang sama:

memory_size<2> 
union_arm_selector<>