{"id":17,"date":"2007-11-19T08:04:54","date_gmt":"2007-11-19T08:04:39","guid":{"rendered":""},"modified":"2017-03-07T16:18:33","modified_gmt":"2017-03-07T16:18:33","slug":"paludis_meets_java_part_ii","status":"publish","type":"post","link":"https:\/\/blogs.gentoo.org\/ferdy\/2007\/11\/19\/paludis_meets_java_part_ii\/","title":{"rendered":"Paludis meets Java, part II"},"content":{"rendered":"<p>After showing how is the structure of a regular Paludis class using JNI, next thing is showing part of the magic behind <tt>paludis_java.hh<\/tt>.<\/p>\n<p>What&#8217;s there is functions to convert Java types into Paludis (and C++ native) types and viceversa (this conversions exist only when needed, not for every single type). So, for instance, one of those conversions would be <tt>jboolean &lt;--&gt; bool<\/tt> and it looks like this:<\/p>\n<pre>inline jboolean to_java_boolean(bool b)\r\n{\r\n    return b ? JNI_TRUE : JNI_FALSE;\r\n}\r\n\r\ninline bool from_java_boolean(jboolean b)\r\n{\r\n    return b == JNI_TRUE;\r\n}<\/pre>\n<p>That was easy, let me show you the <em>dirty<\/em> part. I call it dirty not because it is difficult or tricky to understand, but because it is a bit <em>icky<\/em>. It is the way we store the native Paludis pointers in Java classes:<\/p>\n<pre>inline jlong to_java_ptr(void * const ptr)\r\n{\r\n    return reinterpret_cast&lt;jlong&gt;(ptr);\r\n}\r\n\r\ntemplate &lt;typename T_&gt;\r\ninline T_ * from_java_ptr(jlong ptr)\r\n{\r\n    return reinterpret_cast&lt;_ *&gt;(ptr);\r\n}\r\n\r\ntemplate &lt;typename T_&gt;\r\ninline tr1::shared_ptr&lt;T_&gt; from_java_ptr_sptr(jlong ptr)\r\n{\r\n    return * reinterpret_cast&lt;tr1::shared_ptr&lt;T_&gt; *&gt;(ptr);\r\n}<\/pre>\n<p>Although dirty, it is quite easy aswell. Something this bindings will be converting a lot is strings:<\/p>\n<pre>std::string\r\nfrom_java_string(JNIEnv * const env, jstring s)\r\n{\r\n    const char * const c_s(env-&gt;GetStringUTFChars(s, 0));\r\n    std::string result(c_s);\r\n    env-&gt;ReleaseStringUTFChars(s, c_s);\r\n    return result;\r\n}\r\n\r\njstring\r\nto_java_string(JNIEnv * const env, const std::string &amp; s)\r\n{\r\n    return env-&gt;NewStringUTF(s.c_str());\r\n}<\/pre>\n<p>And since C++ is such a nice language comparing and stringifying arbitrary types was just as easy (credits for this go to Mr. McCreesh):<\/p>\n<pre>template &lt;typename T_&gt;\r\njstring common_stringify(JNIEnv * const env, jlong ptr)\r\n{\r\n    return to_java_string(env, stringify(*from_java_ptr&lt;T_&gt;(ptr)));\r\n}\r\n\r\ntemplate &lt;typename T_&gt;\r\njint common_compare(jlong lhs_ptr, jlong rhs_ptr)\r\n{\r\n    T_ * const lhs(from_java_ptr&lt;T_&gt;(lhs_ptr)), * const rhs(from_java_ptr&lt;T_&gt;(rhs_ptr));\r\n    if (*lhs &lt; *rhs)\r\n        return -1;\r\n    else if (*rhs &lt; *lhs)\r\n        return 1;\r\n    else\r\n        return 0;\r\n}<\/pre>\n<p>This wasn&#8217;t quite difficult and it certainly makes working with JNI easier. However, there is still stuff to do (actually, to show, since it is implemented and working in my git repository) like exception handling, converting arbitrary Paludis types and typesafe containers.<\/p>\n<p>During the weekend I&#8217;ve written bindings for almost every core Paludis class and the patch is not that big:<\/p>\n<pre>[ $ ~\/git\/paludis(jni) ] git diff --shortstat trunk..\r\n 30 files changed, 1975 insertions(+), 0 deletions(-)<\/pre>\n<p>Now it is time to stop the bindings for a while and start writing documentation, examples and integrating the bindings into the Paludis codebase properly.<\/p>\n<p>Next part of the series will be about how I am converting arbitrary types and containers into Java types and typesafe collections respectively.<\/p>\n<p>&mdash; ferdy<\/p>\n","protected":false},"excerpt":{"rendered":"<p>After showing how is the structure of a regular Paludis class using JNI, next thing is showing part of the magic behind paludis_java.hh. What&#8217;s there is functions to convert Java types into Paludis (and C++ native) types and viceversa (this conversions exist only when needed, not for every single type). So, for instance, one of &hellip; <a href=\"https:\/\/blogs.gentoo.org\/ferdy\/2007\/11\/19\/paludis_meets_java_part_ii\/\" class=\"more-link\">Continue reading <span class=\"screen-reader-text\">Paludis meets Java, part II<\/span><\/a><\/p>\n","protected":false},"author":14,"featured_media":0,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":[],"categories":[3,6],"tags":[],"jetpack_featured_media_url":"","_links":{"self":[{"href":"https:\/\/blogs.gentoo.org\/ferdy\/wp-json\/wp\/v2\/posts\/17"}],"collection":[{"href":"https:\/\/blogs.gentoo.org\/ferdy\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/blogs.gentoo.org\/ferdy\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/blogs.gentoo.org\/ferdy\/wp-json\/wp\/v2\/users\/14"}],"replies":[{"embeddable":true,"href":"https:\/\/blogs.gentoo.org\/ferdy\/wp-json\/wp\/v2\/comments?post=17"}],"version-history":[{"count":1,"href":"https:\/\/blogs.gentoo.org\/ferdy\/wp-json\/wp\/v2\/posts\/17\/revisions"}],"predecessor-version":[{"id":49,"href":"https:\/\/blogs.gentoo.org\/ferdy\/wp-json\/wp\/v2\/posts\/17\/revisions\/49"}],"wp:attachment":[{"href":"https:\/\/blogs.gentoo.org\/ferdy\/wp-json\/wp\/v2\/media?parent=17"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/blogs.gentoo.org\/ferdy\/wp-json\/wp\/v2\/categories?post=17"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/blogs.gentoo.org\/ferdy\/wp-json\/wp\/v2\/tags?post=17"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}