How to use Qt Jambi generator
As things stand, Jambi’s generator is highly tailored to work with Qt headers and Java bindings generation. But many people uses it to create their own bindings too, for native Qt/cpp programs. Jambi bindings can be thought only as an example how generator can be used to generate bindings.
Materials fuond from this section should help both Jambi developers and people interested in making Java bindings for Qt based applications or libraries.
In order to be able to do this work, you should be confident with both Java programming and C++ programming. You should also read up on JNI (no magic there, but it will help if you recognize the function calls.) Knowing a little bit of Qt Jambi and Qt, so that you understand the design principles behind the APIs, is also very useful. And you should read up on the Qt Jambi type system[TODO: port the doc, http://doc.trolltech.com/qtjambi-4.5.2_01/com/trolltech/qt/qtjambi-typesystem.html], and try to get familiar with the binding code generated by the Qt Jambi Generator[TODO: port the doc, http://doc.trolltech.com/qtjambi-4.5.2_01/com/trolltech/qt/qtjambi-generator.html].
There is a lot of complexity to manage in the binding code, so try to keep a cool head. Even if you don’t understand each detail in the generated code, it is helpful to understand how a function declaration in C++ ends up as a functioning Java method once you have run the Qt Jambi Generator. Please read the article on the Generator in Qt Quarterly issue 29 [pdf]. This contains an overview of the bindings-layer in Qt Jambi and some reasoning behind the complexities within.
How generator works
The Qt Jambi code generator is a tool that parses C++ header files and generates Java source files and a binding layer based on the Java Native Interface that will tie the Java classes to Qt/C++ classes. It is written to handle Qt/C++ source code, according to the coding patterns known in the Qt/C++ library, and is not intended for mapping C++ in general, such as std, templates etc.
The generator is a command line tool that takes as input a typesystem specification and a header file. When generating code for Qt we specify the typesystem specification file that specifies all typesystem files used in generation and a headerfile that includes Qt master includes (QtCore and QtGui for example, in Linux under /usr/include/qt4). The header files are then preprocessed so all macros and typedefs are expanded. Enums, namespaces and classes are mapped according to how they are specified in the type system. For each C++ class that is encountered, we generate a Java source file, a C++ header file and a C++ source file.
The Java source file contains one public class named as the class in C++. All public and protected members are included in this Java class. Each function generates a native Java function and each field generates a getter and setter function for the field. Using the typsystem it is possible to change access, rename or completly remove a function, or change the read/write access on a field. It is also possible to use the typesystem to inject arbitrary code in the Java source file, such as an extra member function.
C++ implementation files contain two different parts. A subclass of the Qt/C++ class that is being generated, called the “shell” class and the implementation of the native Java functions, declared in the Java source file. The shell classes are primarly there to forward virtual function calls made in C++ into Java, so that we get polymorphic behaviour. It is possible to inject code in the reimplemented virtual functions in the shell classes using the typesystem. The C++ header file is primarly an implementation detail and can be ignored.