diff --git a/include/servicepoint.h b/include/servicepoint.h
index e001ddd..1e0182e 100644
--- a/include/servicepoint.h
+++ b/include/servicepoint.h
@@ -1,7 +1,7 @@
 #ifndef SERVICEPOINT_BINDINGS_C
 #define SERVICEPOINT_BINDINGS_C
 
-/* Generated with cbindgen:0.29.0 */
+/* Generated with cbindgen:0.28.0 */
 
 /* Warning, this file is autogenerated by cbindgen. Don't modify this manually. */
 
@@ -1254,14 +1254,14 @@ void sp_cmd_bitmap_free(struct BitmapCommand */*notnull*/ instance);
 struct BitmapCommand */*notnull*/ sp_cmd_bitmap_from_bitmap(struct Bitmap */*notnull*/ bitmap);
 
 /**
- * Returns a pointer to the provided `BitmapCommand`.
+ * Gets a reference to the field `bitmap` of the [`servicepoint::BitmapCommand`].
  *
- * # Safety
- *
- * - The returned bitmap inherits the lifetime of the command in which it is contained.
+ * - The returned reference inherits the lifetime of object in which it is contained.
  * - The returned pointer may not be used in a function that consumes the instance, e.g. to create a command.
+ *
+ * This function is part of the sp_cmd_bitmap module.
  */
-struct Bitmap */*notnull*/ sp_cmd_bitmap_get(struct BitmapCommand */*notnull*/ command);
+struct Bitmap */*notnull*/ sp_cmd_bitmap_get_bitmap_mut(struct BitmapCommand */*notnull*/ instance);
 
 /**
  * Gets the value of field `compression` of the [`servicepoint::BitmapCommand`].
@@ -1271,7 +1271,9 @@ struct Bitmap */*notnull*/ sp_cmd_bitmap_get(struct BitmapCommand */*notnull*/ c
 CompressionCode sp_cmd_bitmap_get_compression(struct BitmapCommand */*notnull*/ instance);
 
 /**
- * Reads the origin field of the [BitmapCommand].
+ * Reads the origin field of the [`BitmapCommand`].
+ *
+ * This function is part of the sp_cmd_bitmap module.
  */
 void sp_cmd_bitmap_get_origin(struct BitmapCommand */*notnull*/ command,
                               size_t */*notnull*/ origin_x,
@@ -1292,10 +1294,13 @@ struct BitmapCommand */*notnull*/ sp_cmd_bitmap_new(struct Bitmap */*notnull*/ b
                                                     CompressionCode compression);
 
 /**
- * Moves the provided [Bitmap] to be contained in the [BitmapCommand].
+ * Sets the value of field `bitmap` of the [`servicepoint::BitmapCommand`].
+ * The provided value is moved into the instance, potentially invalidating previously taken references.
+ *
+ * This function is part of the sp_cmd_bitmap module.
  */
-void sp_cmd_bitmap_set(struct BitmapCommand */*notnull*/ command,
-                       struct Bitmap */*notnull*/ bitmap);
+void sp_cmd_bitmap_set_bitmap(struct BitmapCommand */*notnull*/ instance,
+                              struct Bitmap */*notnull*/ value);
 
 /**
  * Sets the value of field `compression` of the [`servicepoint::BitmapCommand`].
@@ -1306,7 +1311,9 @@ void sp_cmd_bitmap_set_compression(struct BitmapCommand */*notnull*/ instance,
                                    CompressionCode value);
 
 /**
- * Overwrites the origin field of the [BitmapCommand].
+ * Overwrites the origin field of the [`BitmapCommand`].
+ *
+ * This function is part of the sp_cmd_bitmap module.
  */
 void sp_cmd_bitmap_set_origin(struct BitmapCommand */*notnull*/ command,
                               size_t origin_x,
@@ -1336,9 +1343,14 @@ struct BitVecCommand */*notnull*/ sp_cmd_bitvec_clone(struct BitVecCommand */*no
 void sp_cmd_bitvec_free(struct BitVecCommand */*notnull*/ instance);
 
 /**
- * Returns a pointer to the [BitVec] contained in the [BitVecCommand].
+ * Gets a reference to the field `bitvec` of the [`servicepoint::BitVecCommand`].
+ *
+ * - The returned reference inherits the lifetime of object in which it is contained.
+ * - The returned pointer may not be used in a function that consumes the instance, e.g. to create a command.
+ *
+ * This function is part of the sp_cmd_bitvec module.
  */
-BitVec *sp_cmd_bitvec_get(struct BitVecCommand */*notnull*/ command);
+BitVec */*notnull*/ sp_cmd_bitvec_get_bitvec_mut(struct BitVecCommand */*notnull*/ instance);
 
 /**
  * Gets the value of field `compression` of the [`servicepoint::BitVecCommand`].
@@ -1383,10 +1395,13 @@ struct BitVecCommand */*notnull*/ sp_cmd_bitvec_new(BitVec */*notnull*/ bitvec,
                                                     CompressionCode compression);
 
 /**
- * Moves the provided [BitVec] to be contained in the [BitVecCommand].
+ * Sets the value of field `bitvec` of the [`servicepoint::BitVecCommand`].
+ * The provided value is moved into the instance, potentially invalidating previously taken references.
+ *
+ * This function is part of the sp_cmd_bitvec module.
  */
-void sp_cmd_bitvec_set(struct BitVecCommand */*notnull*/ command,
-                       BitVec */*notnull*/ bitvec);
+void sp_cmd_bitvec_set_bitvec(struct BitVecCommand */*notnull*/ instance,
+                              BitVec */*notnull*/ value);
 
 /**
  * Sets the value of field `compression` of the [`servicepoint::BitVecCommand`].
@@ -1489,12 +1504,19 @@ void sp_cmd_brightness_grid_free(struct BrightnessGridCommand */*notnull*/ insta
 struct BrightnessGridCommand */*notnull*/ sp_cmd_brightness_grid_from_grid(BrightnessGrid */*notnull*/ grid);
 
 /**
- * Returns a pointer to the [BrightnessGrid] contained in the [BrightnessGridCommand].
+ * Gets a reference to the field `grid` of the [`servicepoint::BrightnessGridCommand`].
+ *
+ * - The returned reference inherits the lifetime of object in which it is contained.
+ * - The returned pointer may not be used in a function that consumes the instance, e.g. to create a command.
+ *
+ * This function is part of the sp_cmd_brightness_grid module.
  */
-BrightnessGrid *sp_cmd_brightness_grid_get(struct BrightnessGridCommand */*notnull*/ command);
+BrightnessGrid */*notnull*/ sp_cmd_brightness_grid_get_grid_mut(struct BrightnessGridCommand */*notnull*/ instance);
 
 /**
- * Overwrites the origin field of the [BrightnessGridCommand].
+ * Reads the origin field of the [`BrightnessGridCommand`].
+ *
+ * This function is part of the sp_cmd_brightness_grid module.
  */
 void sp_cmd_brightness_grid_get_origin(struct BrightnessGridCommand */*notnull*/ command,
                                        size_t */*notnull*/ origin_x,
@@ -1523,13 +1545,18 @@ struct BrightnessGridCommand */*notnull*/ sp_cmd_brightness_grid_new(BrightnessG
                                                                      size_t origin_y);
 
 /**
- * Moves the provided [BrightnessGrid] to be contained in the [BrightnessGridCommand].
+ * Sets the value of field `grid` of the [`servicepoint::BrightnessGridCommand`].
+ * The provided value is moved into the instance, potentially invalidating previously taken references.
+ *
+ * This function is part of the sp_cmd_brightness_grid module.
  */
-void sp_cmd_brightness_grid_set(struct BrightnessGridCommand */*notnull*/ command,
-                                BrightnessGrid */*notnull*/ grid);
+void sp_cmd_brightness_grid_set_grid(struct BrightnessGridCommand */*notnull*/ instance,
+                                     BrightnessGrid */*notnull*/ value);
 
 /**
- * Reads the origin field of the [BrightnessGridCommand].
+ * Overwrites the origin field of the [`BrightnessGridCommand`].
+ *
+ * This function is part of the sp_cmd_brightness_grid module.
  */
 void sp_cmd_brightness_grid_set_origin(struct BrightnessGridCommand */*notnull*/ command,
                                        size_t origin_x,
@@ -1558,12 +1585,19 @@ void sp_cmd_char_grid_free(struct CharGridCommand */*notnull*/ instance);
 struct CharGridCommand */*notnull*/ sp_cmd_char_grid_from_grid(CharGrid */*notnull*/ grid);
 
 /**
- * Returns a pointer to the [CharGrid] contained in the [CharGridCommand].
+ * Gets a reference to the field `grid` of the [`servicepoint::CharGridCommand`].
+ *
+ * - The returned reference inherits the lifetime of object in which it is contained.
+ * - The returned pointer may not be used in a function that consumes the instance, e.g. to create a command.
+ *
+ * This function is part of the sp_cmd_char_grid module.
  */
-CharGrid */*notnull*/ sp_cmd_char_grid_get(struct CharGridCommand */*notnull*/ command);
+CharGrid */*notnull*/ sp_cmd_char_grid_get_grid_mut(struct CharGridCommand */*notnull*/ instance);
 
 /**
- * Reads the origin field of the [CharGridCommand].
+ * Reads the origin field of the [`CharGridCommand`].
+ *
+ * This function is part of the sp_cmd_char_grid module.
  */
 void sp_cmd_char_grid_get_origin(struct CharGridCommand */*notnull*/ command,
                                  size_t */*notnull*/ origin_x,
@@ -1583,13 +1617,18 @@ struct CharGridCommand */*notnull*/ sp_cmd_char_grid_new(CharGrid */*notnull*/ g
                                                          size_t origin_y);
 
 /**
- * Moves the provided [CharGrid] to be contained in the [CharGridCommand].
+ * Sets the value of field `grid` of the [`servicepoint::CharGridCommand`].
+ * The provided value is moved into the instance, potentially invalidating previously taken references.
+ *
+ * This function is part of the sp_cmd_char_grid module.
  */
-void sp_cmd_char_grid_set(struct CharGridCommand */*notnull*/ command,
-                          CharGrid */*notnull*/ grid);
+void sp_cmd_char_grid_set_grid(struct CharGridCommand */*notnull*/ instance,
+                               CharGrid */*notnull*/ value);
 
 /**
- * Overwrites the origin field of the [CharGridCommand].
+ * Overwrites the origin field of the [`CharGridCommand`].
+ *
+ * This function is part of the sp_cmd_char_grid module.
  */
 void sp_cmd_char_grid_set_origin(struct CharGridCommand */*notnull*/ command,
                                  size_t origin_x,
@@ -1645,19 +1684,19 @@ void sp_cmd_cp437_grid_free(struct Cp437GridCommand */*notnull*/ instance);
 struct Cp437GridCommand */*notnull*/ sp_cmd_cp437_grid_from_grid(Cp437Grid */*notnull*/ grid);
 
 /**
- * Show text on the screen.
+ * Gets a reference to the field `grid` of the [`servicepoint::Cp437GridCommand`].
  *
- * The text is sent in the form of a 2D grid of [CP-437] encoded characters.
- * For sending UTF-8 encoded characters, see [servicepoint::CharGridCommand].
+ * - The returned reference inherits the lifetime of object in which it is contained.
+ * - The returned pointer may not be used in a function that consumes the instance, e.g. to create a command.
  *
- * [CP-437]: https://en.wikipedia.org/wiki/Code_page_437
+ * This function is part of the sp_cmd_cp437_grid module.
  */
-Cp437Grid *sp_cmd_cp437_grid_get(struct Cp437GridCommand */*notnull*/ command);
+Cp437Grid */*notnull*/ sp_cmd_cp437_grid_get_grid_mut(struct Cp437GridCommand */*notnull*/ instance);
 
 /**
- * Gets the origin field of the [Cp437GridCommand].
+ * Reads the origin field of the [`Cp437GridCommand`].
  *
- * Rust equivalent: `cp437_command.origin`
+ * This function is part of the sp_cmd_cp437_grid module.
  */
 void sp_cmd_cp437_grid_get_origin(struct Cp437GridCommand */*notnull*/ command,
                                   size_t */*notnull*/ origin_x,
@@ -1677,17 +1716,18 @@ struct Cp437GridCommand */*notnull*/ sp_cmd_cp437_grid_new(Cp437Grid */*notnull*
                                                            size_t origin_y);
 
 /**
- * Moves the provided bitmap into the provided command.
+ * Sets the value of field `grid` of the [`servicepoint::Cp437GridCommand`].
+ * The provided value is moved into the instance, potentially invalidating previously taken references.
  *
- * This drops the previously contained [Cp437Grid].
+ * This function is part of the sp_cmd_cp437_grid module.
  */
-void sp_cmd_cp437_grid_set(struct Cp437GridCommand */*notnull*/ command,
-                           Cp437Grid */*notnull*/ grid);
+void sp_cmd_cp437_grid_set_grid(struct Cp437GridCommand */*notnull*/ instance,
+                                Cp437Grid */*notnull*/ value);
 
 /**
- * Sets the origin field of the [Cp437GridCommand].
+ * Overwrites the origin field of the [`Cp437GridCommand`].
  *
- * Rust equivalent: `cp437_command.origin = Origin::new(origin_x, origin_y)`
+ * This function is part of the sp_cmd_cp437_grid module.
  */
 void sp_cmd_cp437_grid_set_origin(struct Cp437GridCommand */*notnull*/ command,
                                   size_t origin_x,
diff --git a/src/commands/bitmap_command.rs b/src/commands/bitmap_command.rs
index f4c9a7e..68f6408 100644
--- a/src/commands/bitmap_command.rs
+++ b/src/commands/bitmap_command.rs
@@ -1,12 +1,22 @@
 use crate::{
+    commands::wrap_origin_accessors,
     macros::{wrap_clone, wrap_fields, wrap_free, wrap_functions},
     mem::{heap_move_nonnull, heap_move_ok, heap_remove},
 };
 use servicepoint::{Bitmap, BitmapCommand, CompressionCode, Origin, Packet};
 use std::ptr::NonNull;
 
-wrap_functions!(sp_cmd_bitmap;
+wrap_clone!(sp_cmd_bitmap::BitmapCommand);
+wrap_free!(sp_cmd_bitmap::BitmapCommand);
 
+wrap_fields!(sp_cmd_bitmap::BitmapCommand;
+    prop bitmap: Bitmap { mut get(); move set(value); };
+    prop compression: CompressionCode { get(); set(value); };
+);
+
+wrap_origin_accessors!(sp_cmd_bitmap::BitmapCommand);
+
+wrap_functions!(sp_cmd_bitmap;
     /// Sets a window of pixels to the specified values.
     ///
     /// The passed [Bitmap] gets consumed.
@@ -43,74 +53,4 @@ wrap_functions!(sp_cmd_bitmap;
     ) -> *mut Packet {
         heap_move_ok(unsafe { heap_remove(command) }.try_into())
     }
-
 );
-
-wrap_clone!(sp_cmd_bitmap::BitmapCommand);
-wrap_free!(sp_cmd_bitmap::BitmapCommand);
-
-wrap_fields!(
-    sp_cmd_bitmap::BitmapCommand;
-    //prop bitmap: NonNull<Bitmap> {
-    //    get() {
-    //        return NonNull::from(bitmap);
-    //    };
-    //    set(value) {
-    //        return  unsafe { heap_remove(value) };
-    //    };
-    //};
-    prop compression: CompressionCode {
-        get();
-        set(value);
-    };
-);
-
-/// Returns a pointer to the provided `BitmapCommand`.
-///
-/// # Safety
-///
-/// - The returned bitmap inherits the lifetime of the command in which it is contained.
-/// - The returned pointer may not be used in a function that consumes the instance, e.g. to create a command.
-#[no_mangle]
-pub unsafe extern "C" fn sp_cmd_bitmap_get(
-    mut command: NonNull<BitmapCommand>,
-) -> NonNull<Bitmap> {
-    unsafe { NonNull::from(&mut (command.as_mut().bitmap)) }
-}
-
-/// Moves the provided [Bitmap] to be contained in the [BitmapCommand].
-#[no_mangle]
-pub unsafe extern "C" fn sp_cmd_bitmap_set(
-    mut command: NonNull<BitmapCommand>,
-    bitmap: NonNull<Bitmap>,
-) {
-    unsafe {
-        command.as_mut().bitmap = heap_remove(bitmap);
-    }
-}
-
-/// Reads the origin field of the [BitmapCommand].
-#[no_mangle]
-pub unsafe extern "C" fn sp_cmd_bitmap_get_origin(
-    command: NonNull<BitmapCommand>,
-    origin_x: NonNull<usize>,
-    origin_y: NonNull<usize>,
-) {
-    unsafe {
-        let origin = &command.as_ref().origin;
-        *origin_x.as_ptr() = origin.x;
-        *origin_y.as_ptr() = origin.y;
-    }
-}
-
-/// Overwrites the origin field of the [BitmapCommand].
-#[no_mangle]
-pub unsafe extern "C" fn sp_cmd_bitmap_set_origin(
-    mut command: NonNull<BitmapCommand>,
-    origin_x: usize,
-    origin_y: usize,
-) {
-    unsafe {
-        command.as_mut().origin = Origin::new(origin_x, origin_y);
-    }
-}
diff --git a/src/commands/bitvec_command.rs b/src/commands/bitvec_command.rs
index 7dfed38..6cec313 100644
--- a/src/commands/bitvec_command.rs
+++ b/src/commands/bitvec_command.rs
@@ -8,6 +8,16 @@ use servicepoint::{
 };
 use std::ptr::NonNull;
 
+wrap_clone!(sp_cmd_bitvec::BitVecCommand);
+wrap_free!(sp_cmd_bitvec::BitVecCommand);
+
+wrap_fields!(sp_cmd_bitvec::BitVecCommand;
+    prop bitvec: DisplayBitVec { mut get(); move set(value); };
+    prop offset: Offset { get(); set(value); };
+    prop operation: BinaryOperation { get(); set(value); };
+    prop compression: CompressionCode { get(); set(value); };
+);
+
 wrap_functions!(sp_cmd_bitvec;
 
     /// Set pixel data starting at the pixel offset on screen.
@@ -46,41 +56,3 @@ wrap_functions!(sp_cmd_bitvec;
     }
 
 );
-
-wrap_clone!(sp_cmd_bitvec::BitVecCommand);
-wrap_free!(sp_cmd_bitvec::BitVecCommand);
-
-wrap_fields!(
-    sp_cmd_bitvec::BitVecCommand;
-    prop offset: Offset {
-        get();
-        set(value);
-    };
-    prop operation: BinaryOperation {
-        get();
-        set(value);
-    };
-    prop compression: CompressionCode {
-        get();
-        set(value);
-    };
-);
-
-/// Returns a pointer to the [BitVec] contained in the [BitVecCommand].
-#[no_mangle]
-pub unsafe extern "C" fn sp_cmd_bitvec_get(
-    mut command: NonNull<BitVecCommand>,
-) -> *mut DisplayBitVec {
-    unsafe { &mut command.as_mut().bitvec }
-}
-
-/// Moves the provided [BitVec] to be contained in the [BitVecCommand].
-#[no_mangle]
-pub unsafe extern "C" fn sp_cmd_bitvec_set(
-    mut command: NonNull<BitVecCommand>,
-    bitvec: NonNull<DisplayBitVec>,
-) {
-    unsafe {
-        command.as_mut().bitvec = heap_remove(bitvec);
-    }
-}
diff --git a/src/commands/brightness_grid_command.rs b/src/commands/brightness_grid_command.rs
index b4e6e23..cc26b77 100644
--- a/src/commands/brightness_grid_command.rs
+++ b/src/commands/brightness_grid_command.rs
@@ -1,10 +1,20 @@
 use crate::{
-    macros::{wrap_clone, wrap_free, wrap_functions},
+    commands::wrap_origin_accessors,
+    macros::{wrap_clone, wrap_fields, wrap_free, wrap_functions},
     mem::{heap_move_nonnull, heap_move_ok, heap_remove},
 };
 use servicepoint::{BrightnessGrid, BrightnessGridCommand, Origin, Packet};
 use std::ptr::NonNull;
 
+wrap_clone!(sp_cmd_brightness_grid::BrightnessGridCommand);
+wrap_free!(sp_cmd_brightness_grid::BrightnessGridCommand);
+
+wrap_fields!(sp_cmd_brightness_grid::BrightnessGridCommand;
+    prop grid: BrightnessGrid { mut get(); move set(grid); };
+);
+
+wrap_origin_accessors!(sp_cmd_brightness_grid::BrightnessGridCommand);
+
 wrap_functions!(sp_cmd_brightness_grid;
 
     /// Set the brightness of individual tiles in a rectangular area of the display.
@@ -41,51 +51,3 @@ wrap_functions!(sp_cmd_brightness_grid;
     }
 
 );
-
-wrap_clone!(sp_cmd_brightness_grid::BrightnessGridCommand);
-wrap_free!(sp_cmd_brightness_grid::BrightnessGridCommand);
-
-/// Moves the provided [BrightnessGrid] to be contained in the [BrightnessGridCommand].
-#[no_mangle]
-pub unsafe extern "C" fn sp_cmd_brightness_grid_set(
-    mut command: NonNull<BrightnessGridCommand>,
-    grid: NonNull<BrightnessGrid>,
-) {
-    unsafe {
-        command.as_mut().grid = heap_remove(grid);
-    }
-}
-
-/// Returns a pointer to the [BrightnessGrid] contained in the [BrightnessGridCommand].
-#[no_mangle]
-pub unsafe extern "C" fn sp_cmd_brightness_grid_get(
-    mut command: NonNull<BrightnessGridCommand>,
-) -> *mut BrightnessGrid {
-    unsafe { &mut command.as_mut().grid }
-}
-
-/// Overwrites the origin field of the [BrightnessGridCommand].
-#[no_mangle]
-pub unsafe extern "C" fn sp_cmd_brightness_grid_get_origin(
-    command: NonNull<BrightnessGridCommand>,
-    origin_x: NonNull<usize>,
-    origin_y: NonNull<usize>,
-) {
-    unsafe {
-        let origin = &command.as_ref().origin;
-        *origin_x.as_ptr() = origin.x;
-        *origin_y.as_ptr() = origin.y;
-    }
-}
-
-/// Reads the origin field of the [BrightnessGridCommand].
-#[no_mangle]
-pub unsafe extern "C" fn sp_cmd_brightness_grid_set_origin(
-    mut command: NonNull<BrightnessGridCommand>,
-    origin_x: usize,
-    origin_y: usize,
-) {
-    unsafe {
-        command.as_mut().origin = Origin::new(origin_x, origin_y);
-    }
-}
diff --git a/src/commands/char_grid_command.rs b/src/commands/char_grid_command.rs
index 0ef90c0..fe97dc0 100644
--- a/src/commands/char_grid_command.rs
+++ b/src/commands/char_grid_command.rs
@@ -1,10 +1,20 @@
 use crate::{
-    macros::{wrap_clone, wrap_free, wrap_functions},
+    commands::wrap_origin_accessors,
+    macros::{wrap_clone, wrap_fields, wrap_free, wrap_functions},
     mem::{heap_move_nonnull, heap_move_ok, heap_remove},
 };
 use servicepoint::{CharGrid, CharGridCommand, Origin, Packet};
 use std::ptr::NonNull;
 
+wrap_clone!(sp_cmd_char_grid::CharGridCommand);
+wrap_free!(sp_cmd_char_grid::CharGridCommand);
+
+wrap_fields!(sp_cmd_char_grid::CharGridCommand;
+    prop grid: CharGrid { mut get(); move set(grid); };
+);
+
+wrap_origin_accessors!(sp_cmd_char_grid::CharGridCommand);
+
 wrap_functions!(sp_cmd_char_grid;
 
     /// Show UTF-8 encoded text on the screen.
@@ -41,51 +51,3 @@ wrap_functions!(sp_cmd_char_grid;
     }
 
 );
-
-wrap_clone!(sp_cmd_char_grid::CharGridCommand);
-wrap_free!(sp_cmd_char_grid::CharGridCommand);
-
-/// Moves the provided [CharGrid] to be contained in the [CharGridCommand].
-#[no_mangle]
-pub unsafe extern "C" fn sp_cmd_char_grid_set(
-    mut command: NonNull<CharGridCommand>,
-    grid: NonNull<CharGrid>,
-) {
-    unsafe {
-        command.as_mut().grid = heap_remove(grid);
-    }
-}
-
-/// Returns a pointer to the [CharGrid] contained in the [CharGridCommand].
-#[no_mangle]
-pub unsafe extern "C" fn sp_cmd_char_grid_get(
-    mut command: NonNull<CharGridCommand>,
-) -> NonNull<CharGrid> {
-    unsafe { NonNull::from(&mut command.as_mut().grid) }
-}
-
-/// Reads the origin field of the [CharGridCommand].
-#[no_mangle]
-pub unsafe extern "C" fn sp_cmd_char_grid_get_origin(
-    command: NonNull<CharGridCommand>,
-    origin_x: NonNull<usize>,
-    origin_y: NonNull<usize>,
-) {
-    unsafe {
-        let origin = &command.as_ref().origin;
-        *origin_x.as_ptr() = origin.x;
-        *origin_y.as_ptr() = origin.y;
-    }
-}
-
-/// Overwrites the origin field of the [CharGridCommand].
-#[no_mangle]
-pub unsafe extern "C" fn sp_cmd_char_grid_set_origin(
-    mut command: NonNull<CharGridCommand>,
-    origin_x: usize,
-    origin_y: usize,
-) {
-    unsafe {
-        command.as_mut().origin = Origin::new(origin_x, origin_y);
-    }
-}
diff --git a/src/commands/cp437_grid_command.rs b/src/commands/cp437_grid_command.rs
index da8380a..25294bb 100644
--- a/src/commands/cp437_grid_command.rs
+++ b/src/commands/cp437_grid_command.rs
@@ -1,10 +1,20 @@
 use crate::{
-    macros::{wrap_clone, wrap_free, wrap_functions},
+    commands::wrap_origin_accessors,
+    macros::{wrap_clone, wrap_fields, wrap_free, wrap_functions},
     mem::{heap_move_nonnull, heap_move_ok, heap_remove},
 };
 use servicepoint::{Cp437Grid, Cp437GridCommand, Origin, Packet};
 use std::ptr::NonNull;
 
+wrap_clone!(sp_cmd_cp437_grid::Cp437GridCommand);
+wrap_free!(sp_cmd_cp437_grid::Cp437GridCommand);
+
+wrap_fields!(sp_cmd_cp437_grid::Cp437GridCommand;
+    prop grid: Cp437Grid { mut get(); move set(grid); };
+);
+
+wrap_origin_accessors!(sp_cmd_cp437_grid::Cp437GridCommand);
+
 wrap_functions!(sp_cmd_cp437_grid;
 
     /// Show text on the screen.
@@ -41,62 +51,3 @@ wrap_functions!(sp_cmd_cp437_grid;
     }
 
 );
-
-wrap_clone!(sp_cmd_cp437_grid::Cp437GridCommand);
-wrap_free!(sp_cmd_cp437_grid::Cp437GridCommand);
-
-/// Moves the provided bitmap into the provided command.
-///
-/// This drops the previously contained [Cp437Grid].
-#[no_mangle]
-pub unsafe extern "C" fn sp_cmd_cp437_grid_set(
-    mut command: NonNull<Cp437GridCommand>,
-    grid: NonNull<Cp437Grid>,
-) {
-    unsafe {
-        command.as_mut().grid = heap_remove(grid);
-    }
-}
-
-/// Show text on the screen.
-///
-/// The text is sent in the form of a 2D grid of [CP-437] encoded characters.
-/// For sending UTF-8 encoded characters, see [servicepoint::CharGridCommand].
-///
-/// [CP-437]: https://en.wikipedia.org/wiki/Code_page_437
-#[no_mangle]
-pub unsafe extern "C" fn sp_cmd_cp437_grid_get(
-    mut command: NonNull<Cp437GridCommand>,
-) -> *mut Cp437Grid {
-    unsafe { &mut command.as_mut().grid }
-}
-
-/// Gets the origin field of the [Cp437GridCommand].
-///
-/// Rust equivalent: `cp437_command.origin`
-#[no_mangle]
-pub unsafe extern "C" fn sp_cmd_cp437_grid_get_origin(
-    command: NonNull<Cp437GridCommand>,
-    origin_x: NonNull<usize>,
-    origin_y: NonNull<usize>,
-) {
-    unsafe {
-        let origin = &command.as_ref().origin;
-        *origin_x.as_ptr() = origin.x;
-        *origin_y.as_ptr() = origin.y;
-    }
-}
-
-/// Sets the origin field of the [Cp437GridCommand].
-///
-/// Rust equivalent: `cp437_command.origin = Origin::new(origin_x, origin_y)`
-#[no_mangle]
-pub unsafe extern "C" fn sp_cmd_cp437_grid_set_origin(
-    mut command: NonNull<Cp437GridCommand>,
-    origin_x: usize,
-    origin_y: usize,
-) {
-    unsafe {
-        command.as_mut().origin = Origin::new(origin_x, origin_y);
-    }
-}
diff --git a/src/commands/mod.rs b/src/commands/mod.rs
index 3cbb99a..a6fa74d 100644
--- a/src/commands/mod.rs
+++ b/src/commands/mod.rs
@@ -13,3 +13,35 @@ pub use brightness_grid_command::*;
 pub use char_grid_command::*;
 pub use cp437_grid_command::*;
 pub use generic_command::*;
+
+macro_rules! wrap_origin_accessors {
+    ( $prefix:ident :: $object_type:ty ) => {
+        $crate::macros::wrap_functions!($prefix;
+            #[doc = concat!(" Reads the origin field of the [`", stringify!($object_type), "`].")]
+            fn get_origin(
+                command: NonNull<$object_type>,
+                origin_x: NonNull<usize>,
+                origin_y: NonNull<usize>,
+            ) {
+                unsafe {
+                    let origin = &command.as_ref().origin;
+                    *origin_x.as_ptr() = origin.x;
+                    *origin_y.as_ptr() = origin.y;
+                }
+            }
+
+            #[doc = concat!(" Overwrites the origin field of the [`", stringify!($object_type), "`].")]
+            fn set_origin(
+                command: NonNull<$object_type>,
+                origin_x: usize,
+                origin_y: usize,
+            ) {
+                unsafe {
+                    $crate::macros::nonnull_as_mut!(command).origin = ::servicepoint::Origin::new(origin_x, origin_y);
+                }
+            }
+        );
+    };
+}
+
+pub(crate) use wrap_origin_accessors;
diff --git a/src/macros.rs b/src/macros.rs
index 8d4ba47..4157f28 100644
--- a/src/macros.rs
+++ b/src/macros.rs
@@ -28,7 +28,7 @@ macro_rules! nonnull_as_ref {
 
 macro_rules! nonnull_as_mut {
     ($ident:ident) => {
-        &mut *$ident.as_ptr()
+        (&mut *$ident.as_ptr())
     };
 }
 
@@ -84,21 +84,37 @@ macro_rules! wrap_fields {
     (
         $prefix:ident :: $object_type:ty;
         $(
-            prop $prop_name:ident : $prop_type:ty {
-                $(
-                get() $({
-                    $(#[$get_meta:meta])*
-                    $(return $get_expr:expr;)?
-                })?;
-                )?
-                $(
-                set($value:ident)
-                $({
-                    $(#[$set_meta:meta])*
-                    $(return $set_expr:expr;)?
-                })?;
-                )?
-            };
+        prop $prop_name:ident : $prop_type:ty {
+            $(
+            get() $({
+                $(#[$get_meta:meta])*
+                $(return $get_expr:expr;)?
+            })?;
+            )?
+
+            $(
+            mut get() $({
+                $(#[$get_mut_meta:meta])*
+                $(return $get_mut_expr:expr;)?
+            })?;
+            )?
+
+            $(
+            set($value:ident)
+            $({
+                $(#[$set_meta:meta])*
+                $(return $set_expr:expr;)?
+            })?;
+            )?
+
+            $(
+            move set( $set_move_value:ident)
+            $({
+                $(#[$set_move_meta:meta])*
+                $(return $set_move_expr:expr;)?
+            })?;
+            )?
+        };
         )+
     ) => {
         paste::paste! {
@@ -106,16 +122,15 @@ macro_rules! wrap_fields {
             $(
                 $(
                 #[doc = concat!(" Gets the value of field `", stringify!($prop_name),
-                    "` of the [`servicepoint::",stringify!($object_type),"`].")]
+                    "` of the [`servicepoint::", stringify!($object_type),"`].")]
                 $($(
                     #[doc = ""]
                     #[$get_meta]
                 )*)?
                 fn [<get _ $prop_name>](
-                    instance: NonNull<$object_type>
+                    instance: ::core::ptr::NonNull<$object_type>
                 ) -> $prop_type {
-                    let instance = unsafe { $crate::macros::nonnull_as_ref!(instance) };
-                    let $prop_name = instance.$prop_name;
+                    let $prop_name = unsafe { $crate::macros::nonnull_as_ref!(instance).$prop_name };
                     $($(
                     let $prop_name = $get_expr;
                     )?)?
@@ -123,6 +138,27 @@ macro_rules! wrap_fields {
                 }
                 )?
 
+                $(
+                #[doc = concat!(" Gets a reference to the field `", stringify!($prop_name),
+                    "` of the [`servicepoint::",stringify!($object_type),"`].")]
+                $($(
+                    #[doc = ""]
+                    #[$get_mut_meta]
+                )*)?
+                #[doc = ""]
+                #[doc = " - The returned reference inherits the lifetime of object in which it is contained."]
+                #[doc = " - The returned pointer may not be used in a function that consumes the instance, e.g. to create a command."]
+                fn [<get _ $prop_name _mut>](
+                    instance: ::core::ptr::NonNull<$object_type>
+                ) -> ::core::ptr::NonNull<$prop_type> {
+                    let $prop_name = unsafe { &mut $crate::macros::nonnull_as_mut!(instance).$prop_name };
+                    $($(
+                    let $prop_name = $get_mut_expr;
+                    )?)?
+                    return ::core::ptr::NonNull::from($prop_name);
+                }
+                )?
+
                 $(
                 #[doc = concat!(" Sets the value of field `", stringify!($prop_name),
                     "` of the [`servicepoint::",stringify!($object_type),"`].")]
@@ -131,7 +167,7 @@ macro_rules! wrap_fields {
                     #[$set_meta]
                 )*)?
                 fn [<set _ $prop_name>](
-                    instance: NonNull<$object_type>,
+                    instance: ::core::ptr::NonNull<$object_type>,
                     value: $prop_type,
                 ) {
                     let instance = unsafe { $crate::macros::nonnull_as_mut!(instance) };
@@ -142,6 +178,29 @@ macro_rules! wrap_fields {
                     instance.$prop_name = value;
                 }
                 )?
+
+                $(
+                #[doc = concat!(" Sets the value of field `", stringify!($prop_name),
+                    "` of the [`servicepoint::",stringify!($object_type),"`].")]
+                #[doc = concat!(" The provided value is moved into the instance, ",
+                    "potentially invalidating previously taken references.")]
+                $($(
+                #[doc = ""]
+                    #[$set_move_meta]
+                )*)?
+                fn [<set _ $prop_name>](
+                    instance: ::core::ptr::NonNull<$object_type>,
+                    value: NonNull<$prop_type>,
+                ) {
+                    let instance = unsafe { $crate::macros::nonnull_as_mut!(instance) };
+                    let value = unsafe { $crate::mem::heap_remove(value) };
+                    $($(
+                    let $set_move_value = value;
+                    let value = $set_move_expr;
+                    )?)?
+                    instance.$prop_name = value;
+                }
+                )?
             )+
             );
         }