[Kde-java] QtJava api via Dynamic Proxies progress - part 1

Richard Dale Richard_Dale at tipitina.demon.co.uk
Wed Aug 20 05:36:54 CEST 2003


I've got kalyptus correctly auto-generating the QtJava sources so that they 
compile without error, all 60000 lines! So there shouldn't be any need to put 
the autogenerated code in the cvs anymore, it can be generated on demand.

The proxy based api has come out looking quite 'pretty' - I think it's worked 
well. Here is an example of how C++ multiple inheritance maps onto the 
QWidget.java class:

public class QWidget extends QObject implements QPaintDeviceInterface {
	public interface QWidgetPublicInterface {
		QMetaObject metaObject();
		...
	}

	protected interface QWidgetProtectedInterface {
		void newQWidget(QWidget parent, String name, int f);
		...
	}

Two internal interfaces are created, on for all the public methods (both 
static and instance ones), and another interface for the protected methods.

A QWidget constructor looks like this pair of methods:

	protected void newQWidget(QWidget parent, String name) {
		proxyProtectedQWidget().newQWidget(parent,name);
	}
	
public QWidget(QWidget parent, String name) {
		super(new Class[] {QWidgetPublicInterface.class,
 QWidgetProtectedInterface.class, null, null, null, null },
 2);
		newQWidget(parent,name);
	}

The call to super() creates an array of Classes large enough to hold all the 
interfaces for the superclasses of QWidget, ie QObject and Qt in this case. 
There are two entries for each class, for the public and the protected 
interfaces.


Next the constructor in QObject is called, and adds its two interfaces to the 
array:

	private static Class[] addInterfaces(Class[] interfaces, int index) {
		interfaces[index] = QObjectPublicInterface.class;
		interfaces[index+1] = QObjectProtectedInterface.class;
		return interfaces;
	}
	protected QObject(Class[] interfaces, int index) {
		super(addInterfaces(interfaces, index), index+2);
	}

The new proxy instance is created at the top level of the heirarchy (Qt in 
this case) with the complete array of interfaces.

public class Qt implements QtSupport {
	protected Object _proxy = null;
...
	
        protected Qt(Class[] interfaces, int index) {
		interfaces[index] = QtPublicInterface.class;
		interfaces[index+1] = QtProtectedInterface.class;
		_proxy = Proxy.newProxyInstance(ClassLoader.getSystemClassLoader(),
			interfaces,
			new SmokeInvocation(this) );
	}

Back in the QWidget constructor, the actual C++ instance can be created by 
invoking the C++ constructor via the newly created proxy:

		newQWidget(parent,name);

QPaintDeviceInterface is just an empty 'marker interface', which both 
QWidget.java and QPaintDevice.java implement, and any method expecting a 
QPaintDevice in C++, will be converted to expect a java QPaintDeviceInterface 
type argument. 

The instance methods for QPaintDevice are copied into the QWidget.java code, 
as they can't be muliply inherited as for C++.

I attached the kalyptusDataDict.pm to a second mail, as it would exceed the 
limit for this list.

-- Richard

Here are the build instructions from the README file, to try it out:

A Java SMOKE adaptor based on Dynamic Proxies

* Copy kalyptusCxxToJava.pm and kalyptusDataDict.pm to kdebindings/kalyptus.
* Build and install kalyptus
* Run the Qt headers through kalyptus, copy the generated sources to a new
	directory 'qt' and compile:

$ kalyptus -fjava $QTDIR/include/*.h
$ mkdir qt
$ cp `cat java_sources` QtSupport.java SmokeInvocation.java qt
$ javac qt/*.java

..it should compile without error. The whole Qt api now maps onto a single
InvocationHandler.invoke() method in SmokeInvocation.java. Instead of 7500
JNI method calls in the first release of QtJava, just that one native method 
is needed.


-------------- next part --------------
A non-text attachment was scrubbed...
Name: qtjava-0.2.tar.gz
Type: application/x-tgz
Size: 25151 bytes
Desc: not available
Url : http://mail.kde.org/pipermail/kde-java/attachments/20030820/7dae3b12/qtjava-0.2.tar-0001.bin


More information about the Kde-java mailing list