Implement Vec<String>
diff --git a/src/cxx.cc b/src/cxx.cc
index b953904..e00fd6a 100644
--- a/src/cxx.cc
+++ b/src/cxx.cc
@@ -280,7 +280,8 @@
 
 #define FOR_EACH_RUST_VEC(MACRO)                                               \
   FOR_EACH_NUMERIC(MACRO)                                                      \
-  MACRO(bool, bool)
+  MACRO(bool, bool)                                                            \
+  MACRO(string, rust::String)
 
 extern "C" {
 FOR_EACH_STD_VECTOR(STD_VECTOR_OPS)
diff --git a/src/rust_vec.rs b/src/rust_vec.rs
index 9ff4bbf..5e7082a 100644
--- a/src/rust_vec.rs
+++ b/src/rust_vec.rs
@@ -1,3 +1,6 @@
+use crate::rust_string::RustString;
+use std::mem::ManuallyDrop;
+
 #[repr(C)]
 pub struct RustVec<T> {
     repr: Vec<T>,
@@ -40,3 +43,37 @@
         self.repr.as_ptr()
     }
 }
+
+impl RustVec<RustString> {
+    pub fn from_vec_string(v: Vec<String>) -> Self {
+        let mut v = ManuallyDrop::new(v);
+        let ptr = v.as_mut_ptr().cast::<RustString>();
+        let len = v.len();
+        let cap = v.capacity();
+        Self::from(unsafe { Vec::from_raw_parts(ptr, len, cap) })
+    }
+
+    pub fn from_ref_vec_string(v: &Vec<String>) -> &Self {
+        Self::from_ref(unsafe { &*(v as *const Vec<String> as *const Vec<RustString>) })
+    }
+
+    pub fn from_mut_vec_string(v: &mut Vec<String>) -> &mut Self {
+        Self::from_mut(unsafe { &mut *(v as *mut Vec<String> as *mut Vec<RustString>) })
+    }
+
+    pub fn into_vec_string(self) -> Vec<String> {
+        let mut v = ManuallyDrop::new(self.repr);
+        let ptr = v.as_mut_ptr().cast::<String>();
+        let len = v.len();
+        let cap = v.capacity();
+        unsafe { Vec::from_raw_parts(ptr, len, cap) }
+    }
+
+    pub fn as_vec_string(&self) -> &Vec<String> {
+        unsafe { &*(&self.repr as *const Vec<RustString> as *const Vec<String>) }
+    }
+
+    pub fn as_mut_vec_string(&mut self) -> &mut Vec<String> {
+        unsafe { &mut *(&mut self.repr as *mut Vec<RustString> as *mut Vec<String>) }
+    }
+}
diff --git a/src/symbols/rust_string.rs b/src/symbols/rust_string.rs
index 63d4ba7..d8e0f4a 100644
--- a/src/symbols/rust_string.rs
+++ b/src/symbols/rust_string.rs
@@ -3,6 +3,11 @@
 use std::slice;
 use std::str;
 
+#[repr(C)]
+pub(crate) struct RustString {
+    repr: String,
+}
+
 #[export_name = "cxxbridge03$string$new"]
 unsafe extern "C" fn string_new(this: &mut MaybeUninit<String>) {
     ptr::write(this.as_mut_ptr(), String::new());
diff --git a/src/symbols/rust_vec.rs b/src/symbols/rust_vec.rs
index 9ce87ab..5465471 100644
--- a/src/symbols/rust_vec.rs
+++ b/src/symbols/rust_vec.rs
@@ -1,8 +1,9 @@
+use super::rust_string::RustString;
 use std::mem;
 use std::ptr;
 
 #[repr(C)]
-pub struct RustVec<T> {
+pub(crate) struct RustVec<T> {
     repr: Vec<T>,
 }
 
@@ -13,38 +14,38 @@
     };
 }
 
-macro_rules! rust_vec_shims_for_primitive {
-    ($ty:ident) => {
+macro_rules! rust_vec_shims {
+    ($segment:expr, $ty:ty) => {
         const_assert_eq!(mem::size_of::<[usize; 3]>(), mem::size_of::<Vec<$ty>>());
         const_assert_eq!(mem::align_of::<usize>(), mem::align_of::<Vec<$ty>>());
 
         const _: () = {
             attr! {
-                #[export_name = concat!("cxxbridge03$rust_vec$", stringify!($ty), "$new")]
+                #[export_name = concat!("cxxbridge03$rust_vec$", $segment, "$new")]
                 unsafe extern "C" fn __new(this: *mut RustVec<$ty>) {
                     ptr::write(this, RustVec { repr: Vec::new() });
                 }
             }
             attr! {
-                #[export_name = concat!("cxxbridge03$rust_vec$", stringify!($ty), "$drop")]
+                #[export_name = concat!("cxxbridge03$rust_vec$", $segment, "$drop")]
                 unsafe extern "C" fn __drop(this: *mut RustVec<$ty>) {
                     ptr::drop_in_place(this);
                 }
             }
             attr! {
-                #[export_name = concat!("cxxbridge03$rust_vec$", stringify!($ty), "$len")]
+                #[export_name = concat!("cxxbridge03$rust_vec$", $segment, "$len")]
                 unsafe extern "C" fn __len(this: *const RustVec<$ty>) -> usize {
                     (*this).repr.len()
                 }
             }
             attr! {
-                #[export_name = concat!("cxxbridge03$rust_vec$", stringify!($ty), "$data")]
+                #[export_name = concat!("cxxbridge03$rust_vec$", $segment, "$data")]
                 unsafe extern "C" fn __data(this: *const RustVec<$ty>) -> *const $ty {
                     (*this).repr.as_ptr()
                 }
             }
             attr! {
-                #[export_name = concat!("cxxbridge03$rust_vec$", stringify!($ty), "$stride")]
+                #[export_name = concat!("cxxbridge03$rust_vec$", $segment, "$stride")]
                 unsafe extern "C" fn __stride() -> usize {
                     mem::size_of::<$ty>()
                 }
@@ -53,6 +54,12 @@
     };
 }
 
+macro_rules! rust_vec_shims_for_primitive {
+    ($ty:ident) => {
+        rust_vec_shims!(stringify!($ty), $ty);
+    };
+}
+
 rust_vec_shims_for_primitive!(bool);
 rust_vec_shims_for_primitive!(u8);
 rust_vec_shims_for_primitive!(u16);
@@ -64,3 +71,5 @@
 rust_vec_shims_for_primitive!(i64);
 rust_vec_shims_for_primitive!(f32);
 rust_vec_shims_for_primitive!(f64);
+
+rust_vec_shims!("string", RustString);