From: vzhang <vz...@an...> - 2008-06-22 07:16:05
|
Thanks Hendrik for sharing your experience. Think I got bottom of the problem and would like to share with you my fix. /* * Fix mapping between C unsigned integer pointer to java long array. * The typemap(argout) handles output part. * Problem: Wrap c api apiname(unsigned * INOUT) with java using swig * typemaps.i (version 1.3.29) * The values in java long array are wrong if the C api * set more than one value through unsigned integer pointer. * If the C api set only one value, the return value to * Java might be ok in some platforms depend on hardware. * Cause: The C unsigned integer takes 4 bytes. Casting the pointer to unsigned * int to jlong pointer will supprise compilation error but lead api * ReleaseLongArrayElements to copy 4*n bytes to 8*n bytes space, when n * is the array length. From JAVA side, half of the array is filled with * data in wrong format, and another half is empty. * Solution:Walk through every unsigned int and put into jlong format. * */ %typemap(argout) unsigned int *INOUT, unsigned int &INOUT { { int i; int arrayLen = JCALL1(GetArrayLength, jenv, $input) -1 ; unsigned int * tmpIp = (unsigned int *) ((void *)arg1 + sizeof(unsigned int) * arrayLen ); jlong * tmpLp = (jlong *) ((void *)arg1 + sizeof(jlong) * arrayLen ); for (i = 0; i<= arrayLen; i++) { *tmpLp-- = *tmpIp-- ; } } JCALL3(ReleaseLongArrayElements, jenv, $input, (jlong *)$1, 0); } /* * Fix mapping between C unsigned integer pointer to java long array. * The typemap(in) handles input part. * Problem: Wrap c api apiname(unsigned * INOUT) with java using swig. * The values in java long array are passed in to C as unsigned * int pointer. * Cause: The C unsigned integer takes 4 bytes. Casting the pointer from jlong * to unsigned int will supprise compilation error but led C api * to take half of the values from jlong array. * Solution:Walk through every jlong value and put into unsigned int format. * */ %typemap(in) unsigned int *INOUT, unsigned int &INOUT { if (!$input) { SWIG_JavaThrowException(jenv, SWIG_JavaNullPointerException, "array null"); return $null; } if (JCALL1(GetArrayLength, jenv, $input) == 0) { SWIG_JavaThrowException(jenv, SWIG_JavaIndexOutOfBoundsException, "Array must contain at least 1 element"); return $null; } $1 = (void *)JCALL2(GetLongArrayElements, jenv, $input, 0); { int i; int arrayLen = JCALL1(GetArrayLength, jenv, $input) -1 ; unsigned int * tmpIp = (unsigned int *) ((void *)arg1 ); jlong * tmpLp = (jlong *) ((void *)arg1) ; for (i = 0; i<= arrayLen; i++) { *tmpIp++ = (unsigned int)*tmpLp++ ; } memset(tmpIp, '\0', sizeof(unsigned int) * arrayLen ); } } Similar fix should go to INPUT and OUTPUT. Appreciate your comment and suggestion. Thanks. Vivi -----Original Message----- From: swi...@li... [mailto:swi...@li...] On Behalf Of Hendrik Maryns Sent: Wednesday, June 18, 2008 5:34 AM To: swi...@li... Subject: Re: [Swig-user] Handle 64 bit JVM vzhang schreef: > I would really appreciate if someone can share his/her experience > dealing with 64 bit JVM with Swig. > > I have a C function void aFuncIntP( unsigned int * INOUT). The > unsigned int * is mapped to long[]. I noticed that high and low 32 > bits of long are switched on java side. For example, I was expecting > long value 50 (0x32). The output is switched to 214748364800 > (0x3200000000). The swig document SWIGDocumentation.htm section 20.8.3 talked about this issue: > > */Sixty four bit JVMs/* > > /If you are using a 64 bit JVM you may have to override the C long, > but probably not C int default mappings. Mappings will be system > dependent, for example long will need remapping on Unix LP64 systems > (long, pointer > 64 bits, int 32 bits), but not on Microsoft 64 bit Windows which will > be using a P64 IL32 (pointer 64 bits and int, long 32 bits) model. > This may be automated in a future version of SWIG. Note that the Java > write once run anywhere philosophy holds true for all pure Java code > when moving to a 64 bit JVM. Unfortunately it won't of course hold > true for JNI code./ > > Wonder if someone can share some light here. I use SWIG with both 32 and 63 bit JVMs, with the same code. It works fine. But then, I do not deal with longs explicitly, but only with objects. H. -- Hendrik Maryns http://tcl.sfs.uni-tuebingen.de/~hendrik/ ================== http://aouw.org Ask smart questions, get good answers: http://www.catb.org/~esr/faqs/smart-questions.html |