@@ -555,3 +555,56 @@ pub extern fn oh_no() -> i32 {
555
555
# fn main () {}
556
556
```
557
557
558
+ # Representing opaque structs
559
+
560
+ Sometimes, a C library wants to provide a pointer to something, but not let you
561
+ know the internal details of the thing it wants. The simplest way is to use a
562
+ ` void * ` argument:
563
+
564
+ ``` c
565
+ void foo (void * arg);
566
+ void bar(void * arg);
567
+ ```
568
+
569
+ We can represent this in Rust with the `c_void` type:
570
+
571
+ ```rust
572
+ # #![feature(libc)]
573
+ extern crate libc;
574
+
575
+ extern "C" {
576
+ pub fn foo(arg: *mut libc::c_void);
577
+ pub fn bar(arg: *mut libc::c_void);
578
+ }
579
+ # fn main() {}
580
+ ```
581
+
582
+ This is a perfectly valid way of handling the situation. However, we can do a bit
583
+ better. To solve this, some C libraries will instead create a ` struct ` , where
584
+ the details and memory layout of the struct are private. This gives some amount
585
+ of type safety. These structures are called ‘opaque’. Here’s an example, in C:
586
+
587
+ ``` c
588
+ struct Foo; /* Foo is a structure, but its contents are not part of the public interface */
589
+ struct Bar;
590
+ void foo (struct Foo * arg);
591
+ void bar(struct Bar * arg);
592
+ ```
593
+
594
+ To do this in Rust, let’s create our own opaque types with `enum`:
595
+
596
+ ```rust
597
+ pub enum Foo {}
598
+ pub enum Bar {}
599
+
600
+ extern "C" {
601
+ pub fn foo(arg: *mut Foo);
602
+ pub fn bar(arg: *mut Bar);
603
+ }
604
+ # fn main() {}
605
+ ```
606
+
607
+ By using an ` enum ` with no variants, we create an opaque type that we can’t
608
+ instantiate, as it has no variants. But because our ` Foo ` and ` Bar ` types are
609
+ different, we’ll get type safety between the two of them, so we cannot
610
+ accidentally pass a pointer to ` Foo ` to ` bar() ` .
0 commit comments