I am trying to understand the SWIG (java c++ binding) but the online documentation seems pretty clumsy and badly organized. Went through few online links but none seem to explain in a naive friendly way. Eg. a) Why do we need typemaps? b) what does below means (please don't give me the documentation wording)
%typemap(jtype)
%typemap(jstype)
%typemap(jni)
%typemap(javain)
c) What is the Director
d) is there any block diagram to see the SWIG and typemaps in action for java c++? I can't find a good concise tutorial for typemaps and the swig documentation is so jumpy that I can't keep track of things.
Why do we need typemaps?
Although the SWIG documentation is usually pretty solid you're right that it's hard to pick up the bigger picture from it.
I find it handy to thing about like this; you can approach SWIG from two different ways:
What is a typemap?
If you've written a JNI interface by hand (I'll keep using that for now, but this applies for pretty much any language you may care to target) one of the things you'll quickly find yourself doing is repeating chunks of code over and over. This happens because usually in any moderately sized library you care to wrap functions will share argument types and return types, patterns for error handling etc.
This is where typemaps come in. At the highest level they're fragments of code that are applied to build up the wrapping of your library. They're matched on the types involved and specify a mapping from something in C (or C++) to an equivalent in Java.
You can think of typemaps as something of a hybrid between Macros in C and templates in C++ - they're pretty simple manipulation of text without a huge deal of understanding of the language itself, but they are type aware and can be specialised, overridden etc. as you might with a C++ template.
What does that actually mean?
In practice the exact typemaps you'll care about in your SWIG interface depend on what language you're targeting - in the examples you showed they're all for something targeting JNI. There's plenty of this in the library of typemaps SWIG ships with, but some of those are more sophisticated than we really need to understand typemaps at the fundamental level.
As mentioned previously typemaps are mappings from the use of a C type to an appropriate wrapping in the target language. However since most languages you'd target have a fair amount of complexity to writing an interface by hand and SWIG needs to produce both Java and some C for you to compile for your interface there are multiple typemaps per C type (and per use of it, e.g. input, output, structure member).
What are these typemaps?
To answer your specific question about what each typemap in your list is used for let's dig a little deeper and see how to work this out for ourselves.
When I'm trying to figure something out about SWIG I usually use a combination of two things to help me do that. Firstly if you run SWIG with
-debug-tmsearchas an extra argument then it tells you exactly what typemaps it's looking at, as well as which ones actually match in the end.As an example the following interface:
When we run
swig -java -debug-tmsearch test.i | grep Searchingwe get the following output:So we can see exactly which typemaps SWIG wants to consider in generating code for our dummy interface. Your list had the main ones here,
in,javaoutandoutare probably the most notable ones missing.This is often very helpful, and gives us enough to work with for my second trick for understanding things: Secondly you can use placeholder text for a typemap and see where it shows up.
For example if we make the following interface file:
Then we can do something like this after running SWIG:
And from that we can begin to understand the context in which each of those typemaps is being applied in the generated code. (Remember that SWIG is basically concatenating the appropriate typemaps together to build this output). So roughly:
jtype- gets used everywhere we need to figure out a corresponding Java type for a C one, in places where the type will actually cross between Java and C. So this is basically for the raw JNI functions.jstype- this is the type we want to present to Java users of our library. It needs to "match" with thejtypesomewhat in that they will be paired together. Sometimes they'll be the same, but for example if you want to pass a pointer around then thejstypewill be a Java proxy object, but thejtypewill be a long. SWIG does have defaults for both of these for most cases though, so often you don't need to touch those.jni- this typemap is the type used for the corresponding JNI function - it's the JNI type equivalent of thejtype, typically it'll bejlongorjobject, again SWIG has defaults here which mean you often don't need to touch it. This is a C type rather than a Java type unlike the previous types.javain- this typemap is Java code rather than a type specifically. It's used in the generated proxy to convert between the exposedjstypeand thejtype. That can be reaching into the proxy object and pulling alongwhich represents a C pointer out of it, or otherwise packing some data somehow, but it can also be just passing an object straight through too.in- this is some code again, this time in C that's responsible for converting from thejnitype into the actual real type needed for the C function call. It shows up in the_wrap.cfile that's generated instead of Java unlike most of the other examples.I find most of these are easiest to understand in the context of the generated code. Docs and words are great and everything, but from my experience it's hard to beat running the tool, reading what's generated and seeing where something you write in a given typemap shows up. (And if it doesn't show up the debug-tmsearch argument can help you understand why).
Directors
Directors are some SWIG logic to handle polymorphism, i.e. virtual functions and the complexity that comes from crossing language boundaries and expecting this to work. If you only write C this doesn't matter, likewise C++ if you don't use the
virtualkeyword.As above there's some extra typemaps involved and they show up in extra generated code, but it's completely explorable with the two techniques I suggested above.