Implement fallible C++ functions
diff --git a/tests/ffi/lib.rs b/tests/ffi/lib.rs
index fd54654..fe6a364 100644
--- a/tests/ffi/lib.rs
+++ b/tests/ffi/lib.rs
@@ -30,6 +30,10 @@
         fn c_take_str(s: &str);
         fn c_take_rust_string(s: String);
         fn c_take_unique_ptr_string(s: UniquePtr<CxxString>);
+
+        fn c_try_return_void() -> Result<()>;
+        fn c_try_return_primitive() -> Result<usize>;
+        fn c_fail_return_primitive() -> Result<usize>;
     }
 
     extern "Rust" {
diff --git a/tests/ffi/tests.cc b/tests/ffi/tests.cc
index 0ec2658..4f36f9b 100644
--- a/tests/ffi/tests.cc
+++ b/tests/ffi/tests.cc
@@ -1,6 +1,7 @@
 #include "tests/ffi/tests.h"
 #include "tests/ffi/lib.rs"
 #include <cstring>
+#include <stdexcept>
 
 extern "C" void cxx_test_suite_set_correct() noexcept;
 extern "C" tests::R *cxx_test_suite_get_box() noexcept;
@@ -91,6 +92,12 @@
   }
 }
 
+void c_try_return_void() {}
+
+size_t c_try_return_primitive() { return 2020; }
+
+size_t c_fail_return_primitive() { throw std::logic_error("logic error"); }
+
 extern "C" C *cxx_test_suite_get_unique_ptr() noexcept {
   return std::unique_ptr<C>(new C{2020}).release();
 }
diff --git a/tests/ffi/tests.h b/tests/ffi/tests.h
index 7cff6fa..6a5f802 100644
--- a/tests/ffi/tests.h
+++ b/tests/ffi/tests.h
@@ -36,4 +36,8 @@
 void c_take_rust_string(rust::String s);
 void c_take_unique_ptr_string(std::unique_ptr<std::string> s);
 
+void c_try_return_void();
+size_t c_try_return_primitive();
+size_t c_fail_return_primitive();
+
 } // namespace tests
diff --git a/tests/test.rs b/tests/test.rs
index a30aefb..d86ebd2 100644
--- a/tests/test.rs
+++ b/tests/test.rs
@@ -38,6 +38,13 @@
             .to_str()
             .unwrap()
     );
+
+    assert_eq!((), ffi::c_try_return_void().unwrap());
+    assert_eq!(2020, ffi::c_try_return_primitive().unwrap());
+    assert_eq!(
+        "logic error",
+        ffi::c_fail_return_primitive().unwrap_err().what(),
+    );
 }
 
 #[test]