@@ -26,3 +26,51 @@ If you're making changes to rustls-ffi, you'll need
26
26
regenerate the header file:
27
27
28
28
make src/rustls.h
29
+
30
+ ## Dynamically Sized Types
31
+
32
+ Many types exposed in this API are wrapped in a ` Box ` or an ` Arc ` , which can be
33
+ straightforwardly turned into a raw pointer and shared with C using ` into_raw ` .
34
+
35
+ However, Rust has a category of [ Dynamically Sized Types] (DSTs), which in particular
36
+ includes [ trait objects] (i.e. ` dyn Foo ` ). DSTs must always be wrapped in a
37
+ pointer type, e.g. ` Box ` , ` Arc ` , ` & ` , ` &mut ` , ` *mut ` , or ` *const ` . When a pointer
38
+ type wraps a DST it's colloquially called a "fat pointer" because it's twice the
39
+ size of a pointer to a sized type. In the case of trait objects, the extra data
40
+ is a pointer to the vtable.
41
+
42
+ Even though Rust supports raw, fat pointers, they are not FFI-safe. Consider
43
+ this example:
44
+
45
+ ``` rust
46
+ extern " C" fn foo (_ : * const dyn ToString ) { }
47
+ ```
48
+
49
+ ```
50
+ warning: `extern` fn uses type `dyn ToString`, which is not FFI-safe
51
+ --> foo.rs:1:22
52
+ |
53
+ 1 | extern "C" fn foo(_: *const dyn ToString) { }
54
+ | ^^^^^^^^^^^^^^^^^^^ not FFI-safe
55
+ |
56
+ = note: trait objects have no C equivalent
57
+ = note: `#[warn(improper_ctypes_definitions)]` on by default
58
+ ```
59
+
60
+ That makes sense: in the C ABI, all pointers are the same size. There is no
61
+ concept of a fat pointer.
62
+
63
+ Since the Rustls API includes some use of trait objects, we need a way to
64
+ represent them in the C ABI. We do that by creating two pointers: an outer,
65
+ thin pointer (usually a ` Box ` ), and an inner, fat pointer (usually an ` Arc ` ).
66
+ For instance:
67
+
68
+ ``` rust
69
+ Box <Arc <dyn ServerCertVerifier >>
70
+ ```
71
+
72
+ This allows us to convert the outer pointer with ` into_raw() ` and pass it back
73
+ and forth across the FFI boundary.
74
+
75
+ [ Dynamically Sized Types ] : https://doc.rust-lang.org/beta/reference/dynamically-sized-types.html
76
+ [ trait objects ] : https://doc.rust-lang.org/beta/reference/types/trait-object.html
0 commit comments