Implement special case types in extern Rust argument position
diff --git a/gen/write.rs b/gen/write.rs
index 81f26b8..eb11470 100644
--- a/gen/write.rs
+++ b/gen/write.rs
@@ -308,6 +308,11 @@
                 write!(out, "&");
             }
             write!(out, "{}", arg.ident);
+            match arg.ty {
+                Type::RustBox(_) => write!(out, ".into_raw()"),
+                Type::UniquePtr(_) => write!(out, ".release()"),
+                _ => {}
+            }
         }
         if indirect_return {
             if !efn.args.is_empty() {
diff --git a/macro/src/expand.rs b/macro/src/expand.rs
index e631e67..ac10b78 100644
--- a/macro/src/expand.rs
+++ b/macro/src/expand.rs
@@ -231,10 +231,21 @@
     let args = efn.args.iter().map(|arg| expand_extern_arg(arg, types));
     let vars = efn.args.iter().map(|arg| {
         let ident = &arg.ident;
-        if types.needs_indirect_abi(&arg.ty) {
+        let var = if types.needs_indirect_abi(&arg.ty) {
             quote!(::std::ptr::read(#ident))
         } else {
             quote!(#ident)
+        };
+        match &arg.ty {
+            Type::Ident(ident) if ident == "String" => quote!(#var.into_string()),
+            Type::RustBox(_) => quote!(::std::boxed::Box::from_raw(#var)),
+            Type::UniquePtr(_) => quote!(::cxx::UniquePtr::from_raw(#var)),
+            Type::Ref(ty) => match &ty.inner {
+                Type::Ident(ident) if ident == "String" => quote!(#var.as_string()),
+                _ => var,
+            },
+            Type::Str(_) => quote!(#var.as_str()),
+            _ => var,
         }
     });
     let mut outparam = None;