Over the last few months, I’ve been working on a project that aims at making JNA & Rococoa much easier to use.

Indeed, these two great projects require that the developer writes Java interfaces that act as headers for the C/Objective-C functions, structures and classes that are to be used on the Java.

Of course, the more interfaces you need, the more tedious this task becomes.

If only we could have a parser that automatically generates all these interfaces, given a set of C headers!

Well… now we have one, and it’s a 100% Java tool (no reuse of GCC or SWIG parsers).

JNAerator (pronounce ‘generator’) simply parses headers in C, Objective-C (and bits of C++) and generates the corresponding JNA and Rococoa Java interfaces.

Edit: I created http://jnaerator.googlecode.com/

Edit (feb. 15th 2009) :The initial post of JNAerator.jar was not working at all. This has been fixed.

I also uploaded JNAerator’s source code on Google Code, under the LGPL-3.0 license.

Status

This is still a work in progress with tons of bugs (+ currently under heavy refactoring), but it is already capable of generating kilometers of usable interfaces.

For instance, it is capable of parsing all of Apple’s frameworks and generating Rococoa interfaces that compile with no hand-modification (well, it was able to do so before the aforementioned refactoring, at least :-D). Some work still needs to be done not to interfere with existing NSObject and NSClass Rococoa-shipped interfaces.

It is also able to parse Visual Studio 2008 solution and project files and use their settings to parse all the headers they declare.

Features

  • handles most of ANSI-C (not everything yet, though), including (but not restricted to) :

    • structs & unions
    • functions and callbacks (including varargs)
    • typedefs
    • constants & enums
    • macro definitions
  • embeds a full-fledged preprocessor (the great thirdparty Apache 2.0-licensed Anarres JCPP library)
  • parses Visual Studio solutions (*.sln) and projects (*.vcproj) files to retrieve source files, preprocessor symbols and include paths
  • knows about standard compilers and SDKs setups (defaults to know where to find core headers in Visual Studio, frameworks under Mac OS X… GCC not handled automatically yet but paths can be added to command line)
  • converts parsed comments to JavaDocs
  • provides multiple choices of function signatures where possible.

    For instance, the function :

    void CopyBytes(char* dest, const char* source, size_t n, const int* intArray);
    

    Would get the following two Java definitions :

    void CopyBytes(ByteByReference destination, ByteByReference source, NativeLong n, IntByReference intArray);
    void CopyBytes(ByteByReference destination, String source, NativeLong n, int[] intArray);
    
  • generates fairly complete Objective-C mappings:
    • may analyze many frameworks at the same time
    • handles all methods added to a class by parsed protocols

In a near future, JNAerator might be plugged with the Java Compiler API so that is produces JARs directly (with embedded sources, so that Javadocs are usable in IDEs, and maybe even with embedded native libraries).

Syntax of JNAerator:

JNAerator accepts several options, a full list of which can be listed with java -jar jnaerator.jar -h.

It uses the usual C-preprocessor options -Ipath, -Dsymbol, -Dsymbol=value plus the following ones :

  • -project projectFile "config|platform": accepts Visual Studio 2008 solution (.sln) and project (.proj) files. XCode support is on my TODO-list. The config platform string is typically “Release Win32”.
  • -framework FrameWorkName : parse all the headers of an Objective-C framework. This is the easiest option to use when generating Rococoa wrappers.
  • -library libraryShortName : sets the name of library for orphan symbols (until next -library argument). Symbols found in Objective-C frameworks will be forced to that framework’s library, and similarly those found in files that belong to parsed Visual Studio or XCode projects will be forced to those project’s libraries.

Other arguments can be source files or whole directories (in which files will be recursively looked for).

Examples

Simple Meaningful Example

java -jar jnaerator.jar -defaultLibrary Test Test.h

java -jar jnaerator.jar -project TestSolution.sln "Release|Win32"

java -jar jnaerator.jar -framework Foundation -framework CoreFoundation -framework CoreGraphics -framework CarbonCore -framework QTKit

Architecture

JNAerator’s core relies on a custom-written ANTLR grammar that knows about C, C++ and Objective-C (+ some Microsoft and GNU extensions).

The parser operates on the output of the Anarres Java C PreProcessor (JCPP) (with very small patches that I recently contributed to its author).

This parser is incomplete (for instance, knows nothing about operators precedence rules in expressions yet) but has decent-enough support for language features needed to generate JNA headers.

The parser’s output is a DOM-like representation of the source code which design was inspired by Apt and Spoon (an amazing project you should try out for Java source modifications, btw).

This memory representation of mixed C/Objective-C gets transformed bit by bit to Java by JNAerator, and then the resulting Java source tree is serialized back to files.

Apart from the parser itself, the source code of JNAerator is not much more than a big dirty hack, but I’m currently working hard to make it presentable to the world :-D.

Licensing

JNAerator relies on the great Anarres JCPP C preprocessor, released under the Apache 2.0 license.

I plan on releasing JNAerator under the Apache 2.0 and/or LGPL license but haven’t made out my choice yet (would be nice to be compatible with licenses of both Anarres JCPP, JNA & Rococoa), so I’ll hold out until at least after the current refactoring to release any source code.

Download

JNAerator.jar

(needs [JNA's jna.jar](https://jna.dev.java.net/servlets/ProjectDocumentList) in the classpath EDIT 16 feb. : ships with JNA )

Helping out

I’d need feedback on what possible users would like to see in this tool, and accurate info on the various preprocessor symbols that are defined by compilers on various platforms and for various target architectures…

Source code should soon be available, so hold on!

Comments are highly welcome 🙂