avoid C++ -> Python -> C++ overheads when passing around function objects
diff --git a/example/example5.cpp b/example/example5.cpp
index 0e1d2cd..3c144f2 100644
--- a/example/example5.cpp
+++ b/example/example5.cpp
@@ -65,6 +65,29 @@
        py::arg("number"));
 }
 
+int dummy_function(int i) { return i + 1; }
+int dummy_function2(int i, int j) { return i + j; }
+std::function<int(int)> roundtrip(std::function<int(int)> f) { 
+    std::cout << "roundtrip.." << std::endl;
+    return f;
+}
+
+void test_dummy_function(const std::function<int(int)> &f) {
+    using fn_type = int (*)(int);
+    auto result = f.target<fn_type>();
+    if (!result) {
+        std::cout << "could not convert to a function pointer." << std::endl;
+        auto r = f(1);
+        std::cout << "eval(1) = " << r << std::endl;
+    } else if (*result == dummy_function) {
+        std::cout << "argument matches dummy_function" << std::endl;
+        auto r = (*result)(1);
+        std::cout << "eval(1) = " << r << std::endl;
+    } else {
+        std::cout << "argument does NOT match dummy_function. This should never happen!" << std::endl;
+    }
+}
+
 void init_ex5(py::module &m) {
     py::class_<Pet> pet_class(m, "Pet");
     pet_class
@@ -113,4 +136,10 @@
             /* p should be cleaned up when the returned function is garbage collected */
         };
     });
+
+    /* Test if passing a function pointer from C++ -> Python -> C++ yields the original pointer */
+    m.def("dummy_function", &dummy_function);
+    m.def("dummy_function2", &dummy_function2);
+    m.def("roundtrip", &roundtrip);
+    m.def("test_dummy_function", &test_dummy_function);
 }
diff --git a/example/example5.py b/example/example5.py
index 1361c75..2526042 100755
--- a/example/example5.py
+++ b/example/example5.py
@@ -54,3 +54,30 @@
 print("func(number=43) = %i" % f(number=43))
 
 test_cleanup()
+
+from example import dummy_function
+from example import dummy_function2
+from example import test_dummy_function
+from example import roundtrip
+
+test_dummy_function(dummy_function)
+test_dummy_function(roundtrip(dummy_function))
+test_dummy_function(lambda x: x + 2)
+
+try:
+    test_dummy_function(dummy_function2)
+    print("Problem!")
+except Exception as e:
+    if 'Incompatible function arguments' in str(e):
+        print("All OK!")
+    else:
+        print("Problem!")
+
+try:
+    test_dummy_function(lambda x, y: x + y)
+    print("Problem!")
+except Exception as e:
+    if 'missing 1 required positional argument' in str(e):
+        print("All OK!")
+    else:
+        print("Problem!")
diff --git a/example/example5.ref b/example/example5.ref
index f32ba3a..c2e8eef 100644
--- a/example/example5.ref
+++ b/example/example5.ref
@@ -1,20 +1,13 @@
 Rabbit is a parrot
-Polly is a parrot
-Molly is a dog
-Woof!
-func(43) = 44
-Payload constructor
-Payload copy constructor
-Payload move constructor
-Payload destructor
-Payload destructor
-Payload destructor
 Rabbit is a parrot
 Polly is a parrot
+Polly is a parrot
 Molly is a dog
+Molly is a dog
+Woof!
 The following error is expected: Incompatible function arguments. The following argument types are supported:
     1. (example.Dog) -> NoneType
-    Invoked with: <Pet object at 0>
+    Invoked with: <example.Pet object at 0>
 Callback function 1 called!
 False
 Callback function 2 called : Hello, x, True, 5
@@ -24,4 +17,22 @@
 Callback function 3 called : Partial object with one argument
 False
 func(43) = 44
+func(43) = 44
 func(number=43) = 44
+Payload constructor
+Payload copy constructor
+Payload move constructor
+Payload destructor
+Payload destructor
+Payload destructor
+argument matches dummy_function
+eval(1) = 2
+roundtrip..
+argument matches dummy_function
+eval(1) = 2
+could not convert to a function pointer.
+eval(1) = 3
+could not convert to a function pointer.
+All OK!
+could not convert to a function pointer.
+All OK!