2

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?

Community
  • 1
  • 1
paleozogt
  • 6,393
  • 11
  • 51
  • 94

2 Answers2

1

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; 
%} 
Frohnzie
  • 3,559
  • 1
  • 21
  • 24
  • Are you being generic or is this the literal typemap? – paleozogt Sep 21 '11 at 22:35
  • Being generic. TYPE should be your type. What I put should be close. – Frohnzie Sep 21 '11 at 22:36
  • I'd need to make a typemap for *every* pointer type? That could get exhaustive. Surely there's a way to specify a rule for all pointers? – paleozogt Sep 21 '11 at 22:41
  • There aren't that many types. I edited my solution. TYPE * should match all pointers. – Frohnzie Sep 21 '11 at 23:07
  • There are potentially hundreds of types. All of the basics (int, char, etc), as well as any number of user-defined struct pointers, etc. For a large library, this could be a pretty big, non-DRY list. – paleozogt Sep 21 '11 at 23:23
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.

paleozogt
  • 6,393
  • 11
  • 51
  • 94