{"id":1671,"date":"2014-12-16T19:38:20","date_gmt":"2014-12-16T19:38:19","guid":{"rendered":"https:\/\/www.couchbase.com\/blog\/?p=1671"},"modified":"2014-12-16T19:38:20","modified_gmt":"2014-12-16T19:38:19","slug":"libcouchbase-c-and-threads-12","status":"publish","type":"post","link":"https:\/\/www.couchbase.com\/blog\/libcouchbase-c-and-threads-12\/","title":{"rendered":"libcouchbase with C++ and threads (1\/2)"},"content":{"rendered":"<p>I decided to play around a bit last week trying to create a more standard set of C++ bindings for libcouchbase.<\/p>\n<p>While libcouchbase is C and is thus fully usable from C++, I had a common and frequent itch to scratch when using libcouchbase in C++ programs &#8212; namely there is no class hierarchy for command or response objects and the libcouchbase interface hardly feels &#8220;friendly&#8221;. So I set out on a pet project to make a standard and generic (in the colloquial sense of the term) interface for libcouchbase in C++. This is a work in progress and may be found at <a href=\"https:\/\/github.com\/couchbaselabs\/lcb-cxx\">https:\/\/github.com\/couchbaselabs\/lcb-cxx<\/a>.<\/p>\n<p>Because maximum compatibility for C++ was desired, I stayed away from using large external libraries like <em>boost<\/em> or <em>C++11<\/em>. These extra bindings can always be layered on top of the &#8220;generic&#8221; C++ bindings, while reversing the process may be more difficult.<\/p>\n<p>The result was a set of bindings that exposed the following semantics:<\/p>\n<h5>Command Objects<\/h5>\n<p>All commands inherit from a Command object; e.g:<\/p>\n<p><span style=\"font-family: monospace, serif; font-size: 1em; white-space: pre-wrap; line-height: 1;\">class Command { };<\/span><\/p>\n<p>All key commands (i.e. set, get, delete) inherit from a <em>KeyCommand<\/em> object which derives from <em>Command<\/em>. The <em>KeyCommand<\/em> object has accessors for key and hashkey, e.g.<\/p>\n<div class=\"geshifilter\">\n<div class=\"cpp geshifilter-cpp\" style=\"font-family:monospace;\">\u00a0<\/div>\n<div class=\"cpp geshifilter-cpp\" style=\"font-family:monospace;\"><span style=\"color: #0000ff;\">class<\/span> KeyCommand <span style=\"color: #008080;\">:<\/span> <span style=\"color: #0000ff;\">public<\/span> Command <span style=\"color: #008000;\">{<\/span><br \/>\n\u00a0 \u00a0 <span style=\"color: #0000ff;\">virtual<\/span> <span style=\"color: #0000ff;\">void<\/span> setKey<span style=\"color: #008000;\">(<\/span><span style=\"color: #0000ff;\">const<\/span> std<span style=\"color: #008080;\">::<\/span><span style=\"color: #007788;\">string<\/span><span style=\"color: #000040;\">&#038;<\/span><span style=\"color: #008000;\">)<\/span> <span style=\"color: #000080;\">=<\/span> <span style=\"color: #0000dd;\">0<\/span><span style=\"color: #008080;\">;<\/span><br \/>\n\u00a0 \u00a0 <span style=\"color: #0000ff;\">virtual<\/span> <span style=\"color: #0000ff;\">void<\/span> setHashKey<span style=\"color: #008000;\">(<\/span><span style=\"color: #0000ff;\">const<\/span> std<span style=\"color: #008080;\">::<\/span><span style=\"color: #007788;\">string<\/span><span style=\"color: #000040;\">&#038;<\/span><span style=\"color: #008000;\">)<\/span> <span style=\"color: #000080;\">=<\/span> <span style=\"color: #0000dd;\">0<\/span><span style=\"color: #008080;\">;<\/span><br \/>\n<span style=\"color: #008000;\">}<\/span><\/div>\n<\/div>\n<p>Three template classes were created to aid with the construction of the command objects. They are instantiated with their T being the C libcouchbase structure which they wrap as their only data member &#8211; &#8211; and thus ensuring that the performance and memory profile of the C++ command class is more or less the same as the C struct (though there is a vtable). These templates provide common setters for commands which accept CAS and\/or an expiration time, e.g.<\/p>\n<div class=\"geshifilter\">\n<div class=\"cpp geshifilter-cpp\" style=\"font-family:monospace;\">\u00a0<\/div>\n<div class=\"cpp geshifilter-cpp\" style=\"font-family:monospace;\"><span style=\"color: #0000ff;\">template<\/span> <span style=\"color: #000080;\"><<\/span><span style=\"color: #0000ff;\">typename<\/span> T<span style=\"color: #000080;\">><\/span> KeyCommand_v0 <span style=\"color: #008000;\">{<\/span><br \/>\n<span style=\"color: #0000ff;\">public<\/span><span style=\"color: #008080;\">:<\/span><br \/>\n\u00a0 \u00a0 \u00a0 \u00a0<span style=\"color: #0000ff;\">void<\/span> setKey<span style=\"color: #008000;\">(<\/span><span style=\"color: #0000ff;\">const<\/span> std<span style=\"color: #008080;\">::<\/span><span style=\"color: #007788;\">string<\/span> <span style=\"color: #000040;\">&#038;<\/span>s<span style=\"color: #008000;\">)<\/span> <span style=\"color: #008000;\">{<\/span><br \/>\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0cmd.<span style=\"color: #007788;\">v<\/span>.<span style=\"color: #007788;\">v0<\/span>.<span style=\"color: #007788;\">key<\/span> <span style=\"color: #000080;\">=<\/span> s.<span style=\"color: #007788;\">c_str<\/span><span style=\"color: #008000;\">(<\/span><span style=\"color: #008000;\">)<\/span><span style=\"color: #008080;\">;<\/span><br \/>\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0cmd.<span style=\"color: #007788;\">v<\/span>.<span style=\"color: #007788;\">v0<\/span>.<span style=\"color: #007788;\">nkey<\/span> <span style=\"color: #000080;\">=<\/span> s.<span style=\"color: #007788;\">size<\/span><span style=\"color: #008000;\">(<\/span><span style=\"color: #008000;\">)<\/span><span style=\"color: #008080;\">;<\/span><br \/>\n\u00a0 \u00a0 \u00a0 <span style=\"color: #008000;\">}<\/span><br \/>\n\u00a0 \u00a0 \u00a0 <span style=\"color: #666666;\">\/\/ &#8230;<\/span><br \/>\n<span style=\"color: #0000ff;\">private<\/span><span style=\"color: #008080;\">:<\/span><br \/>\n\u00a0 \u00a0 T cmd<span style=\"color: #008080;\">;<\/span><br \/>\n<span style=\"color: #008000;\">}<\/span><span style=\"color: #008080;\">;<\/span><\/div>\n<\/div>\n<h5>Response Objects<\/h5>\n<p>Like command objects, the response objects too are provided in a hierarchy; they contain the C lcb_resp_t * as their only data member. Their hierarchy is as follows:<\/p>\n<ol>\n<li>The abstract <em>ResponseBase<\/em> class. This features accessors for keys<\/li>\n<li>The abstract <em>CasResponseBase<\/em> class which inherits <em>ResponseBase<\/em> and provides accessors for the CAS<\/li>\n<li>The <em>Response<T><\/em> class which implements ResponseBase retrieving the key information from T::v.v0.key<\/li>\n<li>The <em>CasResponse<T> <\/em>which inherits from <em>Response<T><\/em> and implements CasResponseBase by providing cas via <em>T::v.v0.cas<\/em><\/li>\n<li>Response-specific classes which provide extra information; e.g. <em>GetResponse<\/em> is implemented as <em>CasResponse<lcb_get_cmd_t><\/em> with additional accessors for the value and flags.<\/li>\n<\/ol>\n<p>In the header, this looks something like this:<\/p>\n<div class=\"geshifilter\">\n<div class=\"cpp geshifilter-cpp\" style=\"font-family:monospace;\">\u00a0<\/div>\n<div class=\"cpp geshifilter-cpp\" style=\"font-family:monospace;\"><span style=\"color: #0000ff;\">class<\/span> ResponseBase <span style=\"color: #008000;\">{<\/span><br \/>\n<span style=\"color: #0000ff;\">public<\/span><span style=\"color: #008080;\">:<\/span><br \/>\n\u00a0 \u00a0 <span style=\"color: #0000ff;\">virtual<\/span> <span style=\"color: #0000ff;\">const<\/span> <span style=\"color: #0000ff;\">void<\/span> <span style=\"color: #000040;\">*<\/span>getKey<span style=\"color: #008000;\">(<\/span>lcb_size_t <span style=\"color: #000040;\">*<\/span>n<span style=\"color: #008000;\">)<\/span> <span style=\"color: #0000ff;\">const<\/span> <span style=\"color: #000080;\">=<\/span> <span style=\"color: #0000dd;\">0<\/span><span style=\"color: #008080;\">;<\/span><br \/>\n\u00a0 \u00a0 std<span style=\"color: #008080;\">::<\/span><span style=\"color: #007788;\">string<\/span> getKey<span style=\"color: #008000;\">(<\/span><span style=\"color: #008000;\">)<\/span> <span style=\"color: #0000ff;\">const<\/span><span style=\"color: #008080;\">;<\/span><br \/>\n<span style=\"color: #008000;\">}<\/span><span style=\"color: #008080;\">;<\/span><\/div>\n<\/div>\n<div>\n<div class=\"geshifilter\">\n<div class=\"cpp geshifilter-cpp\" style=\"font-family:monospace;\"><span style=\"color: #0000ff;\">template<\/span> <span style=\"color: #000080;\"><<\/span><span style=\"color: #0000ff;\">typename<\/span> T, <span style=\"color: #0000ff;\">class<\/span> I<span style=\"color: #000080;\">><\/span><br \/>\n<span style=\"color: #0000ff;\">class<\/span> Response <span style=\"color: #008080;\">:<\/span> <span style=\"color: #0000ff;\">public<\/span> I <span style=\"color: #008000;\">{<\/span><br \/>\n<span style=\"color: #0000ff;\">public<\/span><span style=\"color: #008080;\">:<\/span><br \/>\n\u00a0 \u00a0 <span style=\"color: #0000ff;\">typedef<\/span> T LcbInternalResponse<span style=\"color: #008080;\">;<\/span><br \/>\n\u00a0 \u00a0 <span style=\"color: #0000ff;\">virtual<\/span> <span style=\"color: #0000ff;\">const<\/span> <span style=\"color: #0000ff;\">void<\/span> <span style=\"color: #000040;\">*<\/span> getKey<span style=\"color: #008000;\">(<\/span>lcb_size_t <span style=\"color: #000040;\">*<\/span>n<span style=\"color: #008000;\">)<\/span> <span style=\"color: #0000ff;\">const<\/span> <span style=\"color: #008000;\">{<\/span><br \/>\n\u00a0 \u00a0 \u00a0 \u00a0 <span style=\"color: #000040;\">*<\/span>n <span style=\"color: #000080;\">=<\/span> resp<span style=\"color: #000040;\">&#8211;<\/span><span style=\"color: #000080;\">><\/span>v.<span style=\"color: #007788;\">v0<\/span>.<span style=\"color: #007788;\">nkey<\/span><span style=\"color: #008080;\">;<\/span><br \/>\n\u00a0 \u00a0 \u00a0 \u00a0 <span style=\"color: #0000ff;\">return<\/span> resp<span style=\"color: #000040;\">&#8211;<\/span><span style=\"color: #000080;\">><\/span>v.<span style=\"color: #007788;\">v0<\/span>.<span style=\"color: #007788;\">key<\/span><span style=\"color: #008080;\">;<\/span><br \/>\n\u00a0 \u00a0 <span style=\"color: #008000;\">}<\/span><br \/>\n<span style=\"color: #0000ff;\">protected<\/span><span style=\"color: #008080;\">:<\/span><br \/>\n\u00a0 \u00a0 <span style=\"color: #0000ff;\">const<\/span> T <span style=\"color: #000040;\">*<\/span> resp<span style=\"color: #008080;\">;<\/span><br \/>\n<span style=\"color: #008000;\">}<\/span><span style=\"color: #008080;\">;<\/span><\/div>\n<\/div>\n<\/div>\n<div>\n<div class=\"geshifilter\">\n<div class=\"cpp geshifilter-cpp\" style=\"font-family:monospace;\"><span style=\"color: #0000ff;\">template<\/span> <span style=\"color: #000080;\"><<\/span><span style=\"color: #0000ff;\">typename<\/span> T<span style=\"color: #000080;\">><\/span><br \/>\n<span style=\"color: #0000ff;\">class<\/span> CasResponse <span style=\"color: #008080;\">:<\/span> <span style=\"color: #0000ff;\">public<\/span> Response<span style=\"color: #000080;\"><<\/span>T, CasResponseBase<span style=\"color: #000080;\">><\/span><br \/>\n<span style=\"color: #008000;\">{<\/span><br \/>\n<span style=\"color: #0000ff;\">public<\/span><span style=\"color: #008080;\">:<\/span><br \/>\n\u00a0 \u00a0 <span style=\"color: #0000ff;\">virtual<\/span> lcb_cas_t getCas<span style=\"color: #008000;\">(<\/span><span style=\"color: #008000;\">)<\/span> <span style=\"color: #0000ff;\">const<\/span> <span style=\"color: #008000;\">{<\/span><br \/>\n\u00a0 \u00a0 \u00a0 \u00a0 <span style=\"color: #0000ff;\">return<\/span> Response<span style=\"color: #000080;\"><<\/span>T,CasResponseBase<span style=\"color: #000080;\">><\/span><span style=\"color: #008080;\">::<\/span><span style=\"color: #007788;\">getRawResponse<\/span><span style=\"color: #008000;\">(<\/span><span style=\"color: #008000;\">)<\/span><span style=\"color: #000040;\">&#8211;<\/span><span style=\"color: #000080;\">><\/span>v.<span style=\"color: #007788;\">v0<\/span>.<span style=\"color: #007788;\">cas<\/span><span style=\"color: #008080;\">;<\/span><br \/>\n\u00a0 \u00a0 <span style=\"color: #008000;\">}<\/span><br \/>\n<span style=\"color: #008000;\">}<\/span><span style=\"color: #008080;\">;<\/span><\/div>\n<\/div>\n<div>\u00a0<\/div>\n<div>\n<div class=\"geshifilter\">\n<div class=\"cpp geshifilter-cpp\" style=\"font-family:monospace;\"><span style=\"color: #0000ff;\">class<\/span> ArithmeticResponse <span style=\"color: #008080;\">:<\/span> <span style=\"color: #0000ff;\">public<\/span> CasResponse<span style=\"color: #000080;\"><<\/span>C_ArithResp<span style=\"color: #000080;\">><\/span> <span style=\"color: #008000;\">{<\/span><br \/>\n<span style=\"color: #0000ff;\">public<\/span><span style=\"color: #008080;\">:<\/span><br \/>\n\u00a0 \u00a0 lcb_uint64_t getValue<span style=\"color: #008000;\">(<\/span><span style=\"color: #008000;\">)<\/span> <span style=\"color: #0000ff;\">const<\/span> <span style=\"color: #008000;\">{<\/span> <span style=\"color: #0000ff;\">return<\/span> getRawResponse<span style=\"color: #008000;\">(<\/span><span style=\"color: #008000;\">)<\/span><span style=\"color: #000040;\">&#8211;<\/span><span style=\"color: #000080;\">><\/span>v.<span style=\"color: #007788;\">v0<\/span>.<span style=\"color: #007788;\">value<\/span><span style=\"color: #008080;\">;<\/span> <span style=\"color: #008000;\">}<\/span><br \/>\n<span style=\"color: #008000;\">}<\/span><span style=\"color: #008080;\">;<\/span><\/div>\n<\/div>\n<div>\u00a0<\/div>\n<\/div>\n<div>\u00a0<\/div>\n<\/div>\n<p>Since the response classes are both derived from the templates as well as their pure abstract bases, they can have their common members treated by helper methods and classes, so for example, for a given function called logKey which logs the key from the response, it may be implemented like so:<\/p>\n<div class=\"geshifilter\">\n<div class=\"cpp geshifilter-cpp\" style=\"font-family:monospace;\">\u00a0<\/div>\n<div class=\"cpp geshifilter-cpp\" style=\"font-family:monospace;\"><span style=\"color: #0000ff;\">void<\/span> logKey<span style=\"color: #008000;\">(<\/span>ResponseBase <span style=\"color: #000040;\">*<\/span>resp<span style=\"color: #008000;\">)<\/span> <span style=\"color: #008000;\">{<\/span><br \/>\n\u00a0 \u00a0std<span style=\"color: #008080;\">::<\/span><span style=\"color: #0000dd;\">cout<\/span> <span style=\"color: #000080;\"><<<\/span> resp<span style=\"color: #000040;\">&#8211;<\/span><span style=\"color: #000080;\">><\/span>getKey<span style=\"color: #008000;\">(<\/span><span style=\"color: #008000;\">)<\/span> <span style=\"color: #000080;\"><<<\/span> std<span style=\"color: #008080;\">::<\/span><span style=\"color: #007788;\">endl<\/span><span style=\"color: #008080;\">;<\/span><br \/>\n<span style=\"color: #008000;\">}<\/span><\/div>\n<\/div>\n<p>And then logKey may be called with any response object.<\/p>\n<h5>Callbacks<\/h5>\n<p>Finally I&#39;ve also implemented a callback interface. Since libcouchbase is a C library and uses C callbacks, the following boilerplate for C++ code was rather common<\/p>\n<div class=\"geshifilter\">\n<div class=\"cpp geshifilter-cpp\" style=\"font-family:monospace;\"><span style=\"color: #0000ff;\">extern<\/span> <span style=\"color: #FF0000;\">&#8220;C&#8221;<\/span> <span style=\"color: #008000;\">{<\/span><br \/>\n<span style=\"color: #0000ff;\">static<\/span> <span style=\"color: #0000ff;\">void<\/span> arith_handler<span style=\"color: #008000;\">(<\/span>lcb_t, <span style=\"color: #0000ff;\">const<\/span> <span style=\"color: #0000ff;\">void<\/span> <span style=\"color: #000040;\">*<\/span>cookie, lcb_error_t err, <span style=\"color: #0000ff;\">const<\/span> lcb_arithmetic_response_t <span style=\"color: #000040;\">*<\/span>resp<span style=\"color: #008000;\">)<\/span> <span style=\"color: #008000;\">{<\/span><br \/>\n\u00a0 \u00a0 MyCppObject <span style=\"color: #000040;\">*<\/span>o <span style=\"color: #000080;\">=<\/span> <span style=\"color: #0000ff;\">reinterpret_cast<\/span><span style=\"color: #000080;\"><<\/span>MyCppObject<span style=\"color: #000080;\">><\/span><span style=\"color: #008000;\">(<\/span><span style=\"color: #0000ff;\">const_cast<\/span><span style=\"color: #000080;\"><<\/span><span style=\"color: #0000ff;\">void<\/span><span style=\"color: #000040;\">*<\/span><span style=\"color: #000080;\">><\/span><span style=\"color: #008000;\">(<\/span>cookie<span style=\"color: #008000;\">)<\/span><span style=\"color: #008000;\">)<\/span><span style=\"color: #008080;\">;<\/span><br \/>\n\u00a0 \u00a0 o<span style=\"color: #000040;\">&#8211;<\/span><span style=\"color: #000080;\">><\/span>doSomething<span style=\"color: #008000;\">(<\/span>resp<span style=\"color: #008000;\">)<\/span><span style=\"color: #008080;\">;<\/span><br \/>\n<span style=\"color: #008000;\">}<\/span><br \/>\n<span style=\"color: #008000;\">}<\/span> <span style=\"color: #666666;\">\/\/ extern &#8220;C&#8221;<\/span><\/div>\n<\/div>\n<p>then, to set the callback<\/p>\n<div class=\"geshifilter\">\n<div class=\"c geshifilter-c\" style=\"font-family:monospace;\">lcb_set_arithmetic_callback<span style=\"color: #009900;\">(<\/span>instance<span style=\"color: #339933;\">,<\/span> arith_handler<span style=\"color: #009900;\">)<\/span><span style=\"color: #339933;\">;<\/span><\/div>\n<\/div>\n<p>In the new bindings, callbacks are exposed in a unified object; so that you don&#39;t have to explicitly set handlers &#8211; but simply subclass the ResponseHandler class and implement the <em>onArithmetic(OperationContext *, const ArithmeticResponse *, lcb_error_t)<\/em> method.<\/p>\n<p>If you don&#39;t wish to implement dedicated handlers for generic commands, you can simply implement the <em>onDefault(OperationContext *, const ResponseBase *, lcb_error_t)<\/em> and handle all commands from there.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>I decided to play around a bit last week trying to create a more standard set of C++ bindings for libcouchbase. While libcouchbase is C and is thus fully usable from C++, I had a common and frequent itch to [&hellip;]<\/p>\n","protected":false},"author":38,"featured_media":13873,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"inline_featured_image":false,"footnotes":""},"categories":[1],"tags":[],"ppma_author":[8997],"class_list":["post-1671","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-uncategorized"],"yoast_head":"<!-- This site is optimized with the Yoast SEO Premium plugin v27.3 (Yoast SEO v27.3) - https:\/\/yoast.com\/product\/yoast-seo-premium-wordpress\/ -->\n<title>libcouchbase with C++ and threads (1\/2) - The Couchbase Blog<\/title>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/www.couchbase.com\/blog\/libcouchbase-c-and-threads-12\/\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"libcouchbase with C++ and threads (1\/2)\" \/>\n<meta property=\"og:description\" content=\"I decided to play around a bit last week trying to create a more standard set of C++ bindings for libcouchbase. While libcouchbase is C and is thus fully usable from C++, I had a common and frequent itch to [&hellip;]\" \/>\n<meta property=\"og:url\" content=\"https:\/\/www.couchbase.com\/blog\/libcouchbase-c-and-threads-12\/\" \/>\n<meta property=\"og:site_name\" content=\"The Couchbase Blog\" \/>\n<meta property=\"article:published_time\" content=\"2014-12-16T19:38:19+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/2022\/11\/couchbase-nosql-dbaas.png\" \/>\n\t<meta property=\"og:image:width\" content=\"1800\" \/>\n\t<meta property=\"og:image:height\" content=\"630\" \/>\n\t<meta property=\"og:image:type\" content=\"image\/png\" \/>\n<meta name=\"author\" content=\"Mark Nunberg, Software Engineer, Couchbase\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:label1\" content=\"Written by\" \/>\n\t<meta name=\"twitter:data1\" content=\"Mark Nunberg, Software Engineer, Couchbase\" \/>\n\t<meta name=\"twitter:label2\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data2\" content=\"3 minutes\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\\\/\\\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\\\/\\\/www.couchbase.com\\\/blog\\\/libcouchbase-c-and-threads-12\\\/#article\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/www.couchbase.com\\\/blog\\\/libcouchbase-c-and-threads-12\\\/\"},\"author\":{\"name\":\"Mark Nunberg, Software Engineer, Couchbase\",\"@id\":\"https:\\\/\\\/www.couchbase.com\\\/blog\\\/#\\\/schema\\\/person\\\/76a75284da32b6f257c8e5e156e6e016\"},\"headline\":\"libcouchbase with C++ and threads (1\\\/2)\",\"datePublished\":\"2014-12-16T19:38:19+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\\\/\\\/www.couchbase.com\\\/blog\\\/libcouchbase-c-and-threads-12\\\/\"},\"wordCount\":584,\"commentCount\":1,\"publisher\":{\"@id\":\"https:\\\/\\\/www.couchbase.com\\\/blog\\\/#organization\"},\"image\":{\"@id\":\"https:\\\/\\\/www.couchbase.com\\\/blog\\\/libcouchbase-c-and-threads-12\\\/#primaryimage\"},\"thumbnailUrl\":\"https:\\\/\\\/www.couchbase.com\\\/blog\\\/wp-content\\\/uploads\\\/sites\\\/1\\\/2022\\\/11\\\/couchbase-nosql-dbaas.png\",\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"CommentAction\",\"name\":\"Comment\",\"target\":[\"https:\\\/\\\/www.couchbase.com\\\/blog\\\/libcouchbase-c-and-threads-12\\\/#respond\"]}]},{\"@type\":\"WebPage\",\"@id\":\"https:\\\/\\\/www.couchbase.com\\\/blog\\\/libcouchbase-c-and-threads-12\\\/\",\"url\":\"https:\\\/\\\/www.couchbase.com\\\/blog\\\/libcouchbase-c-and-threads-12\\\/\",\"name\":\"libcouchbase with C++ and threads (1\\\/2) - The Couchbase Blog\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/www.couchbase.com\\\/blog\\\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\\\/\\\/www.couchbase.com\\\/blog\\\/libcouchbase-c-and-threads-12\\\/#primaryimage\"},\"image\":{\"@id\":\"https:\\\/\\\/www.couchbase.com\\\/blog\\\/libcouchbase-c-and-threads-12\\\/#primaryimage\"},\"thumbnailUrl\":\"https:\\\/\\\/www.couchbase.com\\\/blog\\\/wp-content\\\/uploads\\\/sites\\\/1\\\/2022\\\/11\\\/couchbase-nosql-dbaas.png\",\"datePublished\":\"2014-12-16T19:38:19+00:00\",\"breadcrumb\":{\"@id\":\"https:\\\/\\\/www.couchbase.com\\\/blog\\\/libcouchbase-c-and-threads-12\\\/#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\\\/\\\/www.couchbase.com\\\/blog\\\/libcouchbase-c-and-threads-12\\\/\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\\\/\\\/www.couchbase.com\\\/blog\\\/libcouchbase-c-and-threads-12\\\/#primaryimage\",\"url\":\"https:\\\/\\\/www.couchbase.com\\\/blog\\\/wp-content\\\/uploads\\\/sites\\\/1\\\/2022\\\/11\\\/couchbase-nosql-dbaas.png\",\"contentUrl\":\"https:\\\/\\\/www.couchbase.com\\\/blog\\\/wp-content\\\/uploads\\\/sites\\\/1\\\/2022\\\/11\\\/couchbase-nosql-dbaas.png\",\"width\":1800,\"height\":630},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\\\/\\\/www.couchbase.com\\\/blog\\\/libcouchbase-c-and-threads-12\\\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\\\/\\\/www.couchbase.com\\\/blog\\\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"libcouchbase with C++ and threads (1\\\/2)\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\\\/\\\/www.couchbase.com\\\/blog\\\/#website\",\"url\":\"https:\\\/\\\/www.couchbase.com\\\/blog\\\/\",\"name\":\"The Couchbase Blog\",\"description\":\"Couchbase, the NoSQL Database\",\"publisher\":{\"@id\":\"https:\\\/\\\/www.couchbase.com\\\/blog\\\/#organization\"},\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\\\/\\\/www.couchbase.com\\\/blog\\\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"en-US\"},{\"@type\":\"Organization\",\"@id\":\"https:\\\/\\\/www.couchbase.com\\\/blog\\\/#organization\",\"name\":\"The Couchbase Blog\",\"url\":\"https:\\\/\\\/www.couchbase.com\\\/blog\\\/\",\"logo\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\\\/\\\/www.couchbase.com\\\/blog\\\/#\\\/schema\\\/logo\\\/image\\\/\",\"url\":\"https:\\\/\\\/www.couchbase.com\\\/blog\\\/wp-content\\\/uploads\\\/2023\\\/04\\\/admin-logo.png\",\"contentUrl\":\"https:\\\/\\\/www.couchbase.com\\\/blog\\\/wp-content\\\/uploads\\\/2023\\\/04\\\/admin-logo.png\",\"width\":218,\"height\":34,\"caption\":\"The Couchbase Blog\"},\"image\":{\"@id\":\"https:\\\/\\\/www.couchbase.com\\\/blog\\\/#\\\/schema\\\/logo\\\/image\\\/\"}},{\"@type\":\"Person\",\"@id\":\"https:\\\/\\\/www.couchbase.com\\\/blog\\\/#\\\/schema\\\/person\\\/76a75284da32b6f257c8e5e156e6e016\",\"name\":\"Mark Nunberg, Software Engineer, Couchbase\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/d5a465565eb8a3990192957806a9bc2989ba9f52a5f953d988b5e8afff3b6dc7?s=96&d=mm&r=g895cad0986a0ab674fda857b6ba71ce0\",\"url\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/d5a465565eb8a3990192957806a9bc2989ba9f52a5f953d988b5e8afff3b6dc7?s=96&d=mm&r=g\",\"contentUrl\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/d5a465565eb8a3990192957806a9bc2989ba9f52a5f953d988b5e8afff3b6dc7?s=96&d=mm&r=g\",\"caption\":\"Mark Nunberg, Software Engineer, Couchbase\"},\"description\":\"Mark Nunberg is a software engineer working at Couchbase. He maintains the C client library (libcouchbase) as well as the Python client. He also developed the Perl client (for use at his previous company) - which initially led him to working at Couchbase. Prior to joining Couchbase, he worked on distributed and high performance routing systems at an eCommerce analytics firm. Mark studied Linguistics at the Hebrew University of Jerusalem.\",\"url\":\"https:\\\/\\\/www.couchbase.com\\\/blog\\\/author\\\/mark-nunberg\\\/\"}]}<\/script>\n<!-- \/ Yoast SEO Premium plugin. -->","yoast_head_json":{"title":"libcouchbase with C++ and threads (1\/2) - The Couchbase Blog","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/www.couchbase.com\/blog\/libcouchbase-c-and-threads-12\/","og_locale":"en_US","og_type":"article","og_title":"libcouchbase with C++ and threads (1\/2)","og_description":"I decided to play around a bit last week trying to create a more standard set of C++ bindings for libcouchbase. While libcouchbase is C and is thus fully usable from C++, I had a common and frequent itch to [&hellip;]","og_url":"https:\/\/www.couchbase.com\/blog\/libcouchbase-c-and-threads-12\/","og_site_name":"The Couchbase Blog","article_published_time":"2014-12-16T19:38:19+00:00","og_image":[{"width":1800,"height":630,"url":"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/2022\/11\/couchbase-nosql-dbaas.png","type":"image\/png"}],"author":"Mark Nunberg, Software Engineer, Couchbase","twitter_card":"summary_large_image","twitter_misc":{"Written by":"Mark Nunberg, Software Engineer, Couchbase","Est. reading time":"3 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/www.couchbase.com\/blog\/libcouchbase-c-and-threads-12\/#article","isPartOf":{"@id":"https:\/\/www.couchbase.com\/blog\/libcouchbase-c-and-threads-12\/"},"author":{"name":"Mark Nunberg, Software Engineer, Couchbase","@id":"https:\/\/www.couchbase.com\/blog\/#\/schema\/person\/76a75284da32b6f257c8e5e156e6e016"},"headline":"libcouchbase with C++ and threads (1\/2)","datePublished":"2014-12-16T19:38:19+00:00","mainEntityOfPage":{"@id":"https:\/\/www.couchbase.com\/blog\/libcouchbase-c-and-threads-12\/"},"wordCount":584,"commentCount":1,"publisher":{"@id":"https:\/\/www.couchbase.com\/blog\/#organization"},"image":{"@id":"https:\/\/www.couchbase.com\/blog\/libcouchbase-c-and-threads-12\/#primaryimage"},"thumbnailUrl":"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2022\/11\/couchbase-nosql-dbaas.png","inLanguage":"en-US","potentialAction":[{"@type":"CommentAction","name":"Comment","target":["https:\/\/www.couchbase.com\/blog\/libcouchbase-c-and-threads-12\/#respond"]}]},{"@type":"WebPage","@id":"https:\/\/www.couchbase.com\/blog\/libcouchbase-c-and-threads-12\/","url":"https:\/\/www.couchbase.com\/blog\/libcouchbase-c-and-threads-12\/","name":"libcouchbase with C++ and threads (1\/2) - The Couchbase Blog","isPartOf":{"@id":"https:\/\/www.couchbase.com\/blog\/#website"},"primaryImageOfPage":{"@id":"https:\/\/www.couchbase.com\/blog\/libcouchbase-c-and-threads-12\/#primaryimage"},"image":{"@id":"https:\/\/www.couchbase.com\/blog\/libcouchbase-c-and-threads-12\/#primaryimage"},"thumbnailUrl":"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2022\/11\/couchbase-nosql-dbaas.png","datePublished":"2014-12-16T19:38:19+00:00","breadcrumb":{"@id":"https:\/\/www.couchbase.com\/blog\/libcouchbase-c-and-threads-12\/#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/www.couchbase.com\/blog\/libcouchbase-c-and-threads-12\/"]}]},{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/www.couchbase.com\/blog\/libcouchbase-c-and-threads-12\/#primaryimage","url":"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2022\/11\/couchbase-nosql-dbaas.png","contentUrl":"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2022\/11\/couchbase-nosql-dbaas.png","width":1800,"height":630},{"@type":"BreadcrumbList","@id":"https:\/\/www.couchbase.com\/blog\/libcouchbase-c-and-threads-12\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/www.couchbase.com\/blog\/"},{"@type":"ListItem","position":2,"name":"libcouchbase with C++ and threads (1\/2)"}]},{"@type":"WebSite","@id":"https:\/\/www.couchbase.com\/blog\/#website","url":"https:\/\/www.couchbase.com\/blog\/","name":"The Couchbase Blog","description":"Couchbase, the NoSQL Database","publisher":{"@id":"https:\/\/www.couchbase.com\/blog\/#organization"},"potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/www.couchbase.com\/blog\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"en-US"},{"@type":"Organization","@id":"https:\/\/www.couchbase.com\/blog\/#organization","name":"The Couchbase Blog","url":"https:\/\/www.couchbase.com\/blog\/","logo":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/www.couchbase.com\/blog\/#\/schema\/logo\/image\/","url":"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/2023\/04\/admin-logo.png","contentUrl":"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/2023\/04\/admin-logo.png","width":218,"height":34,"caption":"The Couchbase Blog"},"image":{"@id":"https:\/\/www.couchbase.com\/blog\/#\/schema\/logo\/image\/"}},{"@type":"Person","@id":"https:\/\/www.couchbase.com\/blog\/#\/schema\/person\/76a75284da32b6f257c8e5e156e6e016","name":"Mark Nunberg, Software Engineer, Couchbase","image":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/secure.gravatar.com\/avatar\/d5a465565eb8a3990192957806a9bc2989ba9f52a5f953d988b5e8afff3b6dc7?s=96&d=mm&r=g895cad0986a0ab674fda857b6ba71ce0","url":"https:\/\/secure.gravatar.com\/avatar\/d5a465565eb8a3990192957806a9bc2989ba9f52a5f953d988b5e8afff3b6dc7?s=96&d=mm&r=g","contentUrl":"https:\/\/secure.gravatar.com\/avatar\/d5a465565eb8a3990192957806a9bc2989ba9f52a5f953d988b5e8afff3b6dc7?s=96&d=mm&r=g","caption":"Mark Nunberg, Software Engineer, Couchbase"},"description":"Mark Nunberg is a software engineer working at Couchbase. He maintains the C client library (libcouchbase) as well as the Python client. He also developed the Perl client (for use at his previous company) - which initially led him to working at Couchbase. Prior to joining Couchbase, he worked on distributed and high performance routing systems at an eCommerce analytics firm. Mark studied Linguistics at the Hebrew University of Jerusalem.","url":"https:\/\/www.couchbase.com\/blog\/author\/mark-nunberg\/"}]}},"acf":[],"authors":[{"term_id":8997,"user_id":38,"is_guest":0,"slug":"mark-nunberg","display_name":"Mark Nunberg, Software Engineer, Couchbase","avatar_url":"https:\/\/secure.gravatar.com\/avatar\/d5a465565eb8a3990192957806a9bc2989ba9f52a5f953d988b5e8afff3b6dc7?s=96&d=mm&r=g","0":null,"1":"","2":"","3":"","4":"","5":"","6":"","7":"","8":""}],"_links":{"self":[{"href":"https:\/\/www.couchbase.com\/blog\/wp-json\/wp\/v2\/posts\/1671","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.couchbase.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.couchbase.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.couchbase.com\/blog\/wp-json\/wp\/v2\/users\/38"}],"replies":[{"embeddable":true,"href":"https:\/\/www.couchbase.com\/blog\/wp-json\/wp\/v2\/comments?post=1671"}],"version-history":[{"count":0,"href":"https:\/\/www.couchbase.com\/blog\/wp-json\/wp\/v2\/posts\/1671\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.couchbase.com\/blog\/wp-json\/wp\/v2\/media\/13873"}],"wp:attachment":[{"href":"https:\/\/www.couchbase.com\/blog\/wp-json\/wp\/v2\/media?parent=1671"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.couchbase.com\/blog\/wp-json\/wp\/v2\/categories?post=1671"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.couchbase.com\/blog\/wp-json\/wp\/v2\/tags?post=1671"},{"taxonomy":"author","embeddable":true,"href":"https:\/\/www.couchbase.com\/blog\/wp-json\/wp\/v2\/ppma_author?post=1671"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}