
Hello Boosters, I'm developing a JNI library for writing native code in C++ for Java and calling Java code within C++, using JNI as interface to the JVM. Is there any interest in this library? Regards, -- Felipe Magno de Almeida

Hello, I'm attaching the library source code. It is in Boost license 1.0. The library is based on luabind ideas, which is based on Boost.Python. The JNI interface makes a few things much harder, and makes mismatches almost always fatal and almost impossible to discover beforehand, which makes developing for JNI much harder. I'm implementing the features as I need it, so it is very incomplete. But it is possible to register a class like this: javabind::class_ component_class = env.find_class("java/awt/Component"); javabind::register_class ( javabind::reg::class_<awt::component>(component_class) .constructor(boost::bind(boost::value_factory<awt::component>(), _1, _2 , jvm)) .def<javabind::int_(awt::component const&)> ("nativeGetWidth", boost::bind(&awt::component::width, _1)) .def("nativeGetHeight", &awt::component::height) .def("nativeSetX", &awt::component::set_x) .def("nativeSetY", &awt::component::set_y) .def("nativeSetWidth", &awt::component::set_width) .def("nativeSetHeight", &awt::component::set_height) .def("nativeGetX", &awt::component::get_x) .def("nativeGetY", &awt::component::get_y) .def("nativeSetVisible", &awt::component::set_visible) .def("nativeIsVisible", &awt::component::is_visible) .def("nativeSetPreferredSize", &awt::component::set_preferred_size) .def("nativeSetDelay", &awt::component::set_delay) .def("nativeGetPreferredSize", &awt::component::get_preferred_size , "java/awt/Dimension") .def("nativeSetFocus", &awt::component::set_focus) ); And to call a method like this: javabind::method<void(javabind::object)> initxlet = jtv_xlet_class.method <void(javabind::object)>("initXlet", "javax/tv/xlet/XletContext"); initxlet(user_xlet, xlet_context); Any comments are appreciated, Regards, -- Felipe Magno de Almeida

on Sat Jun 16 2012, Felipe Magno de Almeida <felipe.m.almeida-AT-gmail.com> wrote:
1. Last time I looked, it was impossible to do this without a textual 'C' code generation layer. I don't remember enough about the details to describe the reasons, but I'd be interested to know how you get around this if you recognize the limitation to which I'm referring. 2. I know I've been saying this for years, but we really ought to get the langbinding project going rather than adding new variants of Boost.Python for every language to which we might want to bind. -- Dave Abrahams BoostPro Computing http://www.boostpro.com

On Sun, Jun 17, 2012 at 4:50 PM, Dave Abrahams <dave@boostpro.com> wrote:
The code I've pasted doesn't actually tells the whole story, in this case there is also a .java file which implements the Java class. This class file could be generated by the javabind library, but I thought it would be overkill for what I needed and might actually make the loading time longer, since it would have to be generated. I think most of this generation could be done at compile-time, but I didn't pursue this. As is implemented now, for each class registered there is a .java file which loaded automatically in the classpath. This file is like this: -- package java.awt; public abstract class Component implements ImageObserver, Serializable { private static long bootstrap; private long peer; private native void nativeInit(long bootstrap); protected Component() { nativeInit(bootstrap); assert(peer != 0); } private native boolean nativeIsVisible(long peer); public boolean isVisible() { return nativeIsVisible(peer); } [... other member functions ..] } This is tedious, and I would like to automate this, but it is not a must-have feature for me. The nativeInit function is implicit in register_class in the C++ side, and if it doesn't exist or doesn't have the correct signature, a exception is thrown. The mechanism here is that register_class sets bootstrap field with a "virtual table" for C++'s functions and nativeInit. Then when nativeInit is called a 'peer class' (the C++ class) is constructed in peer together with other information about bases and a pointer to the class 'virtual table'. When every function is called the peer field is passed to it, so that the javabind library can find its virtual table and peer class to call. My project must be as portable as possible, so using a generated native function is not very attractive to me. There are a million things that should be done better in the library as it is, specially with regard to static typing. For now every signature uses javabind::object and must find the 'peer class' to access it, or make a Java call by string and etc. The JNI is very limiting though, so for most problems I don't even have a clue on how to make it work.
That would be good. But I surely wouldn't have the resources to help besides the Java and Lua specifics parts.
Regards, -- Felipe Magno de Almeida

on Sun Jun 17 2012, Felipe Magno de Almeida <felipe.m.almeida-AT-gmail.com> wrote:
Oh, right. Java code generation, not 'C'.
You don't have to generate it at (java) runtime. -- Dave Abrahams BoostPro Computing http://www.boostpro.com

On Fri, Jun 22, 2012 at 3:02 PM, Dave Abrahams <dave@boostpro.com> wrote:
on Sun Jun 17 2012, Felipe Magno de Almeida <felipe.m.almeida-AT-gmail.com> wrote:
[snip]
Do you mean what I already do: generate it by writing java code and compiling. Or at compile-time? Or something else? I'm not sure how to generate at compile-time since I would have to also generate a few strings by composing C string constants, at least copying would be necessary. If I'm not missing something.
Thanks in advance, -- Felipe Magno de Almeida

on Tue Jun 26 2012, Felipe Magno de Almeida <felipe.m.almeida-AT-gmail.com> wrote:
I mean that you can build the generation of the Java code into the capabilities of your binding library. Doesn't the C++ binding description contain all the information you need to generate the Java code? If so, you could generate it from C++, -- Dave Abrahams BoostPro Computing http://www.boostpro.com

On Thu, Jun 28, 2012 at 9:14 AM, Dave Abrahams <dave@boostpro.com> wrote:
Yes it does, and yes I can. But generating from C++ might be costly at initialization-time if I had to do it for hundreds of methods, which is the case for me. I will give this a try next week and see if it really performs wells. If you know how to create a contiguous buffer composed with data from c-style strings strictly at compile-time without constexpr that surely would solve any problems I could have with initialization time. You may know how from this code: register_class<my_class>("MyClass") [ function("Foo", &my_class::foo) , function("Bar", &my_class::bar) ]; I can create a contiguous buffer of size N with these strings without copying at runtime? It is easy to learn the sizes at compile-time, which eliminates strlen calls and I can at least allocate the buffer at compile-time, but I really don't know how to avoid copying. Or the compiler just optimizes these copies away at compile-time?
Thanks in advance, -- Felipe Magno de Almeida

on Thu Jun 28 2012, Felipe Magno de Almeida <felipe.m.almeida-AT-gmail.com> wrote:
You can do it earlier than "initialization time," can't you? Invoke the library in a special mode that just generates Java files?
Doubtful. -- Dave Abrahams BoostPro Computing http://www.boostpro.com
participants (3)
-
Daniel Larimer
-
Dave Abrahams
-
Felipe Magno de Almeida