[Kde-java] QtJava rewritten as a SMOKE adaptor?

Richard Dale Richard_Dale at tipitina.demon.co.uk
Tue Aug 12 12:05:17 CEST 2003


On Tuesday 12 August 2003 09:22, Gert-Jan van der Heiden wrote:
> > > But that doesn't program nice:
> > > QApplicationInterface application  = QApplication.getInstace();
> > > instead of:
> > > QApplication application = new Application();
> >
> > No it should look like the second way. Inside the QApplication
> > constructor, it would look something like this:
> >
> > proxy = (QApplicationInterface) Proxy.newProxyInstance(
> >  						QApplication.class.getClassLoader(),
> >  						new Class[] { QApplicationInterface.class },
> >  						new QtProxy() );
> > newApplication(args);
> >
> > The InvocationHandler class 'QtProxy' would have a built in method called
> > 'setQt', and an instance variable '_qt', which would take a long that was
> > the address of a new QApplication instance returned by the C++
> > constructor in the smoke library. That would be done inside the
> > newApplication() call above, and the 'proxy' would need to forward
> > 'setQt' calls to the QtProxy instance.
>
> Ok, I roughly understand. You'll need the address of the C++ object if you
> wan't to make a call to SMOKE it in invoke method of QtProxy. But how do
> you plan to intercept calls to QApplication, e.g. QApplication.exec() ?
I think QtProxy is a confusing name, it should be called SmokeInvocation 
instead. The method in QApplication.java will look like this:

public int exec() {
        return proxy.exec().intValue();
}

The exec call will be forwarded on to the SmokeInvocation via 'proxy'. Then in 
SmokeInvocation.invoke():

invoke(Object proxy, Method method, Object[] args)

It first needs to look up the Smoke methodId - an int which uniquely 
identifies each Qt C++ method. Smoke adds C++ 'reflection' to the Qt library 
(like the moc does, but for everything), and so the C++ arg types for the 
methods that have the same name as 'Method method', are matched against the 
java arg types in 'Object[] args'. 

To call the method, it will need a C++ class called 'MethodCall'. Here is the 
ruby version - 'VALUE * _sp' is the equivalent of 'Object[] args', and that 
array of args get passed to the MethodCall constructor. Then each java value 
is converted to its equivalent C++ value on the 'Smoke::Stack', and the 
method called. 

class MethodCall : public Marshall {
    int _cur;
    Smoke *_smoke;
    Smoke::Stack _stack;
    Smoke::Index _method;
    Smoke::Index *_args;
    VALUE *_sp;
    int _items;
    VALUE _retval;
    bool _called;
public:
    MethodCall(Smoke *smoke, Smoke::Index method, VALUE *sp, int items) :
...

There will be another C++ class called 'ReturnValue' which takes the C++ 
return value and marshalls it back into the java equivalent. SmokeInvocation 
returns it to the calling Java method. 

An intValue() call is needed in QApplication.exec() because the return value 
from proxy will be an 'Integer':

public int exec() {
        return proxy.exec().intValue();
}

-- Richard



More information about the Kde-java mailing list