From kde-bindings Thu Aug 07 16:27:10 2003 From: Richard Dale Date: Thu, 07 Aug 2003 16:27:10 +0000 To: kde-bindings Subject: [Kde-bindings] QtJava rewritten as a SMOKE adaptor? X-MARC-Message: https://marc.info/?l=kde-bindings&m=106027360724686 I've spent the last month or so implementing QtRuby, which interfaces with Ashley Winter's language independent SMOKE bindings for Qt. It went really well, and already QtRuby can do things that QtJava can't - such as override all virtual methods, rather than just some of them. The advantage of using SMOKE is that you only need to write a relatively simple 'adaptor' for a new language. You don't have to start all over everytime and generate all the 'bridge' C++ classes that actually call the Qt C++ methods, and do virtual method callbacks to the target language - that's all in the SMOKE library. The existing QtJava/Koala java bindings work well enough, but are quite hard to extend for things like adding all the missing virtual method callbacks, java serialization or dynamic DCOP support. So I've been thinking about how to implement the same thing for QtJava for the past couple of days, and can see how it might work now. At the moment each Qt C++ method has a corresponding java native method, and the code in the JNI method calls the C++ one like this: In QApplication.java: public native int exec(); In QApplication.cpp: JNIEXPORT jint JNICALL Java_org_kde_qt_QApplication_exec(JNIEnv *env, jobject obj) { return (jint) ((QApplication*) QtSupport::getQt(env, obj))->exec(); } The getQt() call just gets the corresponding C++ instance for the java one, and calls QApplication::exec() with it. The new SMOKE approach will do away with the need to generate all the C++ JNI based sources like QApplication.cpp/QApplication.h and so on - a BIG plus. The current 90000 lines of C++ code in the project will drop to about 3000. Instead, exec() in QApplication.java will look like this: public int exec() { return proxy.exec().intValue(); } Rather than directly use a native JNI method, the call to exec is handed off to a java.lang.reflect.Proxy instance - 'proxy'. Java Proxies only implement one method to do anything, called invoke(), and the exec() call is translated into an invoke() one via reflection machinery in Proxy. public Object invoke(Object proxy, Method method, Object[] args); invoke() will then call a single global JNI function which actually marshalls the java argument values onto the C++ smoke stack, and invokes the target C++ method via the SMOKE runtime. The 'proxy' instance variables will need to be created in the constructors. Every Qt class like QApplication.java will need to have a corresponding interface QApplicationInterface.java so that all the methods the proxy expects to handle can be given via an array of these interface classes (for the current class and its parents). QApplicationInterface proxy; ... proxy = (QApplicationInterface) Proxy.newProxyInstance( QApplication.class.getClassLoader(), new Class[] { QApplicationInterface.class }, new QtProxy() ); I don't know if this makes sense, but I thought it would be a good idea to at least start discussing what to do about QtJava/Koala for KDE 3.2. -- Richard _______________________________________________ Kde-bindings mailing list Kde-bindings@mail.kde.org http://mail.kde.org/mailman/listinfo/kde-bindings