It seems that SWIG pointer-casting is broken:
*(int **)&jresult = result; // shenanigans
return jresult;
It really should just be
jresult= (jlong)result;
How can I hook into SWIG to tell it how to cast?
You could use a typemap. See doc here for more info. Probably look something like the code below.
%typemap(out) TYPE *
%{
*($&1_ltype)&$result = (jlong)$1;
%}
While Frohnzie's answer is technically correct (it's what I asked for, after all), the best solution is not to hack how SWIG does casting, but to pass -fno-strict-aliasing
to gcc.
Buried in the SWIG docs it specifically says what to do:
Important
If you are going to use optimisations turned on with gcc (for example -O2), ensure you also compile with -fno-strict-aliasing. The GCC optimisations have become more aggressive from gcc-4.0 onwards and will result in code that fails with strict aliasing optimisations turned on. See the C/C++ to Java typemaps section for more details.