diff --git a/c/opendht.cpp b/c/opendht.cpp
index 2d78c62d42efd57e375e773767424059cfe2f819..408b640b22c59f03a9ad870fc9b9071abdc9a5d5 100644
--- a/c/opendht.cpp
+++ b/c/opendht.cpp
@@ -165,7 +165,8 @@ void dht_runner_get(dht_runner* r, const dht_infohash* h, dht_get_cb cb, dht_don
     runner->get(*hash, [cb,cb_user_data](std::shared_ptr<dht::Value> value){
         return cb(reinterpret_cast<const dht_value*>(&value), cb_user_data);
     }, [done_cb, cb_user_data](bool ok){
-        done_cb(ok, cb_user_data);
+        if (done_cb)
+            done_cb(ok, cb_user_data);
     });
 }
 
@@ -192,11 +193,23 @@ void dht_runner_cancel_listen(dht_runner* r, const dht_infohash* h, dht_op_token
     runner->cancelListen(*hash, std::move(*token));
 }
 
+void dht_runner_put(dht_runner* r, const dht_infohash* h, const dht_value* v, dht_done_cb done_cb, void* cb_user_data)
+{
+    auto runner = reinterpret_cast<dht::DhtRunner*>(r);
+    auto hash = reinterpret_cast<const dht::InfoHash*>(h);
+    auto value = reinterpret_cast<const ValueSp*>(v);
+    runner->put(*hash, *value, [done_cb, cb_user_data](bool ok){
+        if (done_cb)
+            done_cb(ok, cb_user_data);
+    });
+}
+
 void dht_runner_shutdown(dht_runner* r, dht_shutdown_cb done_cb, void* cb_user_data)
 {
     auto runner = reinterpret_cast<dht::DhtRunner*>(r);
     runner->shutdown([done_cb, cb_user_data](){
-        done_cb(cb_user_data);
+        if (done_cb)
+            done_cb(cb_user_data);
     });
 }
 
diff --git a/c/opendht_c.h b/c/opendht_c.h
index 19c138d2908be368e2975e1fea53303bfb04b01e..d388aa599cc55e2d5616b8c3e8f3236c8007e7cd 100644
--- a/c/opendht_c.h
+++ b/c/opendht_c.h
@@ -89,6 +89,7 @@ OPENDHT_C_PUBLIC void dht_runner_bootstrap(dht_runner* runner, const char* host,
 OPENDHT_C_PUBLIC void dht_runner_get(dht_runner* runner, const dht_infohash* hash, dht_get_cb cb, dht_done_cb done_cb, void* cb_user_data);
 OPENDHT_C_PUBLIC dht_op_token* dht_runner_listen(dht_runner* runner, const dht_infohash* hash, dht_value_cb cb, void* cb_user_data);
 OPENDHT_C_PUBLIC void dht_runner_cancel_listen(dht_runner* runner, const dht_infohash* hash, dht_op_token* token);
+OPENDHT_C_PUBLIC void dht_runner_put(dht_runner* runner, const dht_infohash* hash, const dht_value* value, dht_done_cb done_cb, void* cb_user_data);
 OPENDHT_C_PUBLIC void dht_runner_shutdown(dht_runner* runner, dht_shutdown_cb done_cb, void* cb_user_data);
 
 #ifdef __cplusplus