OLD | NEW |
1 # C bindings guide | 1 # C bindings guide |
2 | 2 |
3 The Mojo C bindings are a way to talk the Mojom protocol, the canonical protocol | 3 The Mojo C bindings are a way to talk the Mojom protocol, the canonical protocol |
4 for communication between Mojo programs. The library under `bindings/` provides | 4 for communication between Mojo programs. The library under `bindings/` provides |
5 functionality for encoding, decoding and other computation, so it needs to be | 5 functionality for encoding, decoding and other computation, so it needs to be |
6 linked together with C code generated from .mojom files. These C bindings are | 6 linked together with C code generated from .mojom files. These C bindings are |
7 lower-level than the C++ bindings (or any other language, for that matter), | 7 lower-level than the C++ bindings (or any other language, for that matter), |
8 are more error-prone, and require some knowledge of the C Mojo API and the | 8 are more error-prone, and require some knowledge of the C Mojo API and the |
9 mojom encoding format. This document assumes the reader knows about (or knows | 9 mojom encoding format. This document assumes the reader knows about (or knows |
10 how to look up) this relevant information. Consequently, C bindings can also | 10 how to look up) this relevant information. Consequently, C bindings can also |
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
54 struct, with some restrictions; in the example above, we see that the order of | 54 struct, with some restrictions; in the example above, we see that the order of |
55 the fields is different between the mojom and C structs, since the generated C | 55 the fields is different between the mojom and C structs, since the generated C |
56 structs are in packing order, not ordinal order. Although not applicable in this | 56 structs are in packing order, not ordinal order. Although not applicable in this |
57 example, there may be additional fields inserted in the generated C struct for | 57 example, there may be additional fields inserted in the generated C struct for |
58 padding purposes -- since 4-byte data types need to be 4-byte aligned, the | 58 padding purposes -- since 4-byte data types need to be 4-byte aligned, the |
59 generated C bindings may include some fields not explicitly present in the | 59 generated C bindings may include some fields not explicitly present in the |
60 mojom. Since it's not immediately obvious where padding fields could be | 60 mojom. Since it's not immediately obvious where padding fields could be |
61 inserted, it helps to examine the generated C struct to make sure what the | 61 inserted, it helps to examine the generated C struct to make sure what the |
62 fields are, and if possible, set them using field initializers. The | 62 fields are, and if possible, set them using field initializers. The |
63 `example_PersonPtr` union is used to represent an offset in the encoded form, or | 63 `example_PersonPtr` union is used to represent an offset in the encoded form, or |
64 a pointer in the unencoded form. | 64 a pointer in the unencoded form. |
65 | 65 |
66 Since mojom objects appear in depth-first order relative to their parent object, | 66 Since mojom objects appear in depth-first order relative to their parent object, |
67 we can use a `struct MojomBuffer` and calls to `MojomBuffer_Allocate(..)` to | 67 we can use a `struct MojomBuffer` and calls to `MojomBuffer_Allocate(..)` to |
68 linearly allocate space. The struct needs to be constructed and provided by the | 68 linearly allocate space. The struct needs to be constructed and provided by the |
69 user, and it contains 3 fields: A pointer to the buffer, size of the buffer in | 69 user, and it contains 3 fields: A pointer to the buffer, size of the buffer in |
70 bytes, and the byte-position of the next allocation, typically set to 0. | 70 bytes, and the byte-position of the next allocation, typically set to 0. |
71 | 71 |
72 For instance, to allocate space for the `name` parameter of an `example_Person`, | 72 For instance, to allocate space for the `name` parameter of an `example_Person`, |
73 we can do so this way: | 73 we can do so this way: |
74 ```C | 74 ```C |
75 char byte_buffer[512] = {0}; | 75 char byte_buffer[512] = {0}; |
76 struct MojomBuffer buf = {byte_buffer, sizeof(byte_buffer), 0}; | 76 struct MojomBuffer buf = {byte_buffer, sizeof(byte_buffer), 0}; |
77 | 77 |
78 // First allocate space for the example_Person struct: | 78 // First allocate space for the example_Person struct: |
79 struct example_Person* person = | 79 struct example_Person* person = |
80 (struct example_Person*)MojomBuffer_Allocate(&buf, sizeof(struct example_Pers
on)); | 80 (struct example_Person*)MojomBuffer_Allocate(&buf, sizeof(struct example_Pers
on)); |
81 | 81 |
82 // Allocate enough space for a 10 character string. | 82 // Allocate enough space for a 10 character string. |
83 person->name.ptr = (struct MojomStringHeader*)MojomBuffer_Allocate( | 83 person->name.ptr = (struct MojomStringHeader*)MojomBuffer_Allocate( |
84 &buf, | 84 &buf, |
85 sizeof(struct MojomStringHeader) + 10); | 85 sizeof(struct MojomStringHeader) + 10); |
86 ``` | 86 ``` |
87 | 87 |
88 We can extract how much buffer space was used by reading `buf.num_byes_used`. | 88 We can extract how much buffer space was used by reading `buf.num_byes_used`. |
89 | 89 |
90 Along with the C struct, there are some functions generated that help encode and | 90 Along with the C struct, there are some functions generated that help encode and |
91 decode mojom structs, amongst other things. For the `example.Person` mojom | 91 decode mojom structs, amongst other things. For the `example.Person` mojom |
92 struct, the following functions are generated: | 92 struct, the following functions are generated: |
93 | 93 |
94 ```c | 94 ```c |
95 struct example_Person* example_Person_DeepCopy( | 95 struct example_Person* example_Person_DeepCopy( |
96 struct MojomBuffer* in_buffer, | 96 struct MojomBuffer* in_buffer, |
97 struct example_Person* in_data); | 97 struct example_Person* in_data); |
98 | 98 |
99 void example_Person_EncodePointersAndHandles( | 99 void example_Person_EncodePointersAndHandles( |
100 struct example_Person* inout_struct, uint32_t in_struct_size, | 100 struct example_Person* inout_struct, uint32_t in_struct_size, |
101 struct MojomHandleBuffer* inout_handle_buffer); | 101 struct MojomHandleBuffer* inout_handle_buffer); |
102 | 102 |
103 void example_Person_DecodePointersAndHandles( | 103 void example_Person_DecodePointersAndHandles( |
104 struct example_Person* inout_struct, uint32_t in_struct_size, | 104 struct example_Person* inout_struct, uint32_t in_struct_size, |
105 MojomHandle inout_handles[], uin32_t in_num_handles); | 105 MojomHandle inout_handles[], uin32_t in_num_handles); |
106 | 106 |
107 MojomValidationResult example_Person_Validate( | 107 MojomValidationResult example_Person_Validate( |
108 const struct example_Person* in_struct, uint32_t in_struct_size, | 108 const struct example_Person* in_struct, uint32_t in_struct_size, |
109 uint32_t in_num_handles); | 109 uint32_t in_num_handles); |
110 ``` | 110 ``` |
111 | 111 |
112 The generated `example_Person_DeepCopy(..)` function is used to copy over the | 112 The generated `example_Person_DeepCopy(..)` function is used to copy over the |
(...skipping 110 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
223 | 223 |
224 If valid, it is safe to look at the `request_id` in `struct MojomMessage`, and | 224 If valid, it is safe to look at the `request_id` in `struct MojomMessage`, and |
225 the `ordinal` describing the message. By checking if it's any of | 225 the `ordinal` describing the message. By checking if it's any of |
226 `example_EmployeeRegistry_*__Ordinal`, you can further validate that it is a | 226 `example_EmployeeRegistry_*__Ordinal`, you can further validate that it is a |
227 request or expects a response. See `bindings/message.h` for more functions that | 227 request or expects a response. See `bindings/message.h` for more functions that |
228 help validate message headers. Once the message header is fully validated, you | 228 help validate message headers. Once the message header is fully validated, you |
229 must also validate the request or response mojom struct following the message | 229 must also validate the request or response mojom struct following the message |
230 header using the generated `*_Validate(..)` function. | 230 header using the generated `*_Validate(..)` function. |
231 | 231 |
232 Note that validation is run on encoded messages and structs on the wire -- | 232 Note that validation is run on encoded messages and structs on the wire -- |
233 decoding a struct without validating it first is dangerous. | 233 decoding a struct without validating it first is dangerous. |
234 | 234 |
235 ## Enums and Constants | 235 ## Enums and Constants |
236 | 236 |
237 Example mojom code: | 237 Example mojom code: |
238 ``` mojom | 238 ``` mojom |
239 module example; | 239 module example; |
240 | 240 |
241 enum MyEnum { Zero, One, Four = 4, Five }; | 241 enum MyEnum { Zero, One, Four = 4, Five }; |
242 const uint64 kMyConst = 34; | 242 const uint64 kMyConst = 34; |
243 ``` | 243 ``` |
(...skipping 119 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
363 | 363 |
364 ## Maps | 364 ## Maps |
365 | 365 |
366 Maps on the wire are mojom structs with two arrays; one for the keys, and one | 366 Maps on the wire are mojom structs with two arrays; one for the keys, and one |
367 for the values. The `i`th element in the keys array corresponds to the `i`th | 367 for the values. The `i`th element in the keys array corresponds to the `i`th |
368 element in the values array. As such, both arrays must have the same number | 368 element in the values array. As such, both arrays must have the same number |
369 of elements, and neither may be null. | 369 of elements, and neither may be null. |
370 | 370 |
371 # Additional Readings | 371 # Additional Readings |
372 * [Internals of the generated bindings](INTERNALS.md) | 372 * [Internals of the generated bindings](INTERNALS.md) |
OLD | NEW |