use new makeObject to improve API

This commit is contained in:
Eric House 2020-08-15 16:13:24 -07:00
parent 2338b6e017
commit 458872c886
12 changed files with 68 additions and 69 deletions

View file

@ -1891,8 +1891,7 @@ public class BoardDelegate extends DelegateBase
@Override @Override
public void playerScoreHeld( int player ) public void playerScoreHeld( int player )
{ {
LastMoveInfo lmi = new LastMoveInfo(); LastMoveInfo lmi = XwJNI.model_getPlayersLastScore( m_jniGamePtr, player );
XwJNI.model_getPlayersLastScore( m_jniGamePtr, player, lmi );
String expl = lmi.format( m_activity ); String expl = lmi.format( m_activity );
if ( null == expl || 0 == expl.length() ) { if ( null == expl || 0 == expl.length() ) {
expl = getString( R.string.no_moves_made ); expl = getString( R.string.no_moves_made );
@ -2170,10 +2169,8 @@ public class BoardDelegate extends DelegateBase
} else if ( isVisible() ) { } else if ( isVisible() ) {
Utils.playNotificationSound( m_activity ); Utils.playNotificationSound( m_activity );
} else { } else {
LastMoveInfo lmi = new LastMoveInfo();
XwJNI.model_getPlayersLastScore( m_jniGamePtr, turn, lmi );
GameUtils.BackMoveResult bmr = new GameUtils.BackMoveResult(); GameUtils.BackMoveResult bmr = new GameUtils.BackMoveResult();
bmr.m_lmi = lmi; bmr.m_lmi = XwJNI.model_getPlayersLastScore( m_jniGamePtr, turn );
boolean[] locals = m_gi.playersLocal(); boolean[] locals = m_gi.playersLocal();
GameUtils.postMoveNotification( m_activity, m_rowid, GameUtils.postMoveNotification( m_activity, m_rowid,
bmr, locals[turn] ); bmr, locals[turn] );

View file

@ -249,8 +249,7 @@ public class DictBrowseDelegate extends DelegateBase
Assert.assertNotNull( m_browseState ); Assert.assertNotNull( m_browseState );
m_dict = XwJNI.makeDict( pairs.m_bytes[0], m_name, pairs.m_paths[0] ); m_dict = XwJNI.makeDict( pairs.m_bytes[0], m_name, pairs.m_paths[0] );
mDictInfo = new DictInfo(); mDictInfo = XwJNI.dict_getInfo( m_dict, false );
XwJNI.dict_getInfo( m_dict, false, mDictInfo );
setTitle( getString( R.string.dict_browse_title_fmt, m_name, mDictInfo.wordCount ) ); setTitle( getString( R.string.dict_browse_title_fmt, m_name, mDictInfo.wordCount ) );
ExpandImageButton eib = (ExpandImageButton)findViewById( R.id.expander ); ExpandImageButton eib = (ExpandImageButton)findViewById( R.id.expander );

View file

@ -495,16 +495,13 @@ public class DictLangCache {
String[] names = { dal.name }; String[] names = { dal.name };
DictUtils.DictPairs pairs = DictUtils.openDicts( context, names ); DictUtils.DictPairs pairs = DictUtils.openDicts( context, names );
info = new DictInfo(); info = XwJNI.dict_getInfo( pairs.m_bytes[0], dal.name,
if ( XwJNI.dict_getInfo( pairs.m_bytes[0], dal.name, pairs.m_paths[0],
pairs.m_paths[0], DictLoc.DOWNLOAD == dal.loc );
DictLoc.DOWNLOAD == dal.loc, if ( null != info ) {
info ) ) {
info.name = dal.name; info.name = dal.name;
DBUtils.dictsSetInfo( context, dal, info ); DBUtils.dictsSetInfo( context, dal, info );
} else { } else {
info = null;
Log.i( TAG, "getInfo(): unable to open dict %s", dal.name ); Log.i( TAG, "getInfo(): unable to open dict %s", dal.name );
} }
} }

View file

@ -579,8 +579,8 @@ public class DictUtils {
boolean ok = file.endsWith( XWConstants.DICT_EXTN ); boolean ok = file.endsWith( XWConstants.DICT_EXTN );
if ( ok && null != dir ) { if ( ok && null != dir ) {
String fullPath = new File( dir, file ).getPath(); String fullPath = new File( dir, file ).getPath();
ok = XwJNI.dict_getInfo( null, removeDictExtn( file ), fullPath, ok = null != XwJNI.dict_getInfo( null, removeDictExtn( file ),
true, null ); fullPath, true );
} }
return ok; return ok;
} }

View file

@ -578,15 +578,13 @@ public class GameConfigDelegate extends DelegateBase
m_gi = new CurGameInfo( m_giOrig ); m_gi = new CurGameInfo( m_giOrig );
} }
m_carOrig = new CommsAddrRec();
if ( XwJNI.game_hasComms( gamePtr ) ) { if ( XwJNI.game_hasComms( gamePtr ) ) {
XwJNI.comms_getAddr( gamePtr, m_carOrig ); m_carOrig = XwJNI.comms_getAddr( gamePtr );
m_remoteAddrs = XwJNI.comms_getAddrs( gamePtr ); m_remoteAddrs = XwJNI.comms_getAddrs( gamePtr );
} else if ( !localOnlyGame() ) { } else if ( !localOnlyGame() ) {
String relayName = XWPrefs.getDefaultRelayHost( m_activity ); String relayName = XWPrefs.getDefaultRelayHost( m_activity );
int relayPort = XWPrefs.getDefaultRelayPort( m_activity ); int relayPort = XWPrefs.getDefaultRelayPort( m_activity );
XwJNI.comms_getInitialAddr( m_carOrig, relayName, m_carOrig = XwJNI.comms_getInitialAddr( relayName, relayPort );
relayPort );
} }
// load if the first time through.... // load if the first time through....

View file

@ -137,8 +137,7 @@ public class GameUtils {
try ( GamePtr gamePtr = loadMakeGame( context, gi, lockSrc ) ) { try ( GamePtr gamePtr = loadMakeGame( context, gi, lockSrc ) ) {
if ( XwJNI.game_hasComms( gamePtr ) ) { if ( XwJNI.game_hasComms( gamePtr ) ) {
addr = new CommsAddrRec(); addr = XwJNI.comms_getAddr( gamePtr );
XwJNI.comms_getAddr( gamePtr, addr );
} }
} }
@ -1066,9 +1065,7 @@ public class GameUtils {
bmr.m_chatFrom = feedImpl.m_chatFrom; bmr.m_chatFrom = feedImpl.m_chatFrom;
bmr.m_chatTs = feedImpl.m_ts; bmr.m_chatTs = feedImpl.m_ts;
} else { } else {
LastMoveInfo lmi = new LastMoveInfo(); bmr.m_lmi = XwJNI.model_getPlayersLastScore( gamePtr, -1 );
XwJNI.model_getPlayersLastScore( gamePtr, -1, lmi );
bmr.m_lmi = lmi;
} }
} }

View file

@ -206,14 +206,11 @@ public class XwJNI {
public static NetLaunchInfo nliFromStream( byte[] stream ) public static NetLaunchInfo nliFromStream( byte[] stream )
{ {
NetLaunchInfo nli = new NetLaunchInfo(); return nli_from_stream( getJNI().m_ptrGlobals, stream );
nli_from_stream( getJNI().m_ptrGlobals, nli, stream );
return nli;
} }
public static native void comms_getInitialAddr( CommsAddrRec addr, public static native CommsAddrRec comms_getInitialAddr( String relayHost,
String relayHost, int relayPort );
int relayPort );
public static native String comms_getUUID(); public static native String comms_getUUID();
// Game methods // Game methods
@ -414,9 +411,8 @@ public class XwJNI {
boolean gameOver ); boolean gameOver );
public static native int model_getNMoves( GamePtr gamePtr ); public static native int model_getNMoves( GamePtr gamePtr );
public static native int model_getNumTilesInTray( GamePtr gamePtr, int player ); public static native int model_getNumTilesInTray( GamePtr gamePtr, int player );
public static native void model_getPlayersLastScore( GamePtr gamePtr, public static native LastMoveInfo model_getPlayersLastScore( GamePtr gamePtr,
int player, int player );
LastMoveInfo lmi );
// Server // Server
public static native void server_reset( GamePtr gamePtr ); public static native void server_reset( GamePtr gamePtr );
public static native void server_handleUndo( GamePtr gamePtr ); public static native void server_handleUndo( GamePtr gamePtr );
@ -438,7 +434,7 @@ public class XwJNI {
public static native void comms_start( GamePtr gamePtr ); public static native void comms_start( GamePtr gamePtr );
public static native void comms_stop( GamePtr gamePtr ); public static native void comms_stop( GamePtr gamePtr );
public static native void comms_resetSame( GamePtr gamePtr ); public static native void comms_resetSame( GamePtr gamePtr );
public static native void comms_getAddr( GamePtr gamePtr, CommsAddrRec addr ); public static native CommsAddrRec comms_getAddr( GamePtr gamePtr );
public static native CommsAddrRec[] comms_getAddrs( GamePtr gamePtr ); public static native CommsAddrRec[] comms_getAddrs( GamePtr gamePtr );
public static native void comms_augmentHostAddr( GamePtr gamePtr, CommsAddrRec addr ); public static native void comms_augmentHostAddr( GamePtr gamePtr, CommsAddrRec addr );
public static native void comms_dropHostAddr( GamePtr gamePtr, CommsConnType typ ); public static native void comms_dropHostAddr( GamePtr gamePtr, CommsConnType typ );
@ -529,17 +525,17 @@ public class XwJNI {
public static native boolean dict_tilesAreSame( long dict1, long dict2 ); public static native boolean dict_tilesAreSame( long dict1, long dict2 );
public static native String[] dict_getChars( long dict ); public static native String[] dict_getChars( long dict );
public static boolean dict_getInfo( byte[] dict, String name, String path, public static DictInfo dict_getInfo( byte[] dict, String name, String path,
boolean check, DictInfo info ) boolean check )
{ {
DictWrapper wrapper = makeDict( dict, name, path ); DictWrapper wrapper = makeDict( dict, name, path );
return dict_getInfo( wrapper, check, info ); return dict_getInfo( wrapper, check );
} }
public static boolean dict_getInfo( DictWrapper dict, boolean check, DictInfo info ) public static DictInfo dict_getInfo( DictWrapper dict, boolean check )
{ {
return dict_getInfo( getJNI().m_ptrGlobals, dict.getDictPtr(), return dict_getInfo( getJNI().m_ptrGlobals, dict.getDictPtr(),
check, info ); check );
} }
public static String dict_getDesc( DictWrapper dict ) public static String dict_getDesc( DictWrapper dict )
@ -677,8 +673,7 @@ public class XwJNI {
private static native void gi_from_stream( long jniState, CurGameInfo gi, private static native void gi_from_stream( long jniState, CurGameInfo gi,
byte[] stream ); byte[] stream );
private static native byte[] nli_to_stream( long jniState, NetLaunchInfo nli ); private static native byte[] nli_to_stream( long jniState, NetLaunchInfo nli );
private static native void nli_from_stream( long jniState, NetLaunchInfo nli, private static native NetLaunchInfo nli_from_stream( long jniState, byte[] stream );
byte[] stream );
private static native long initGameJNI( long jniState, int seed ); private static native long initGameJNI( long jniState, int seed );
private static native void envDone( long globals ); private static native void envDone( long globals );
private static native long dict_make( long jniState, byte[] dict, String name, String path ); private static native long dict_make( long jniState, byte[] dict, String name, String path );
@ -688,8 +683,8 @@ public class XwJNI {
private static native String dict_tilesToStr( long dictPtr, byte[] tiles, String delim ); private static native String dict_tilesToStr( long dictPtr, byte[] tiles, String delim );
private static native boolean dict_hasDuplicates( long dictPtr ); private static native boolean dict_hasDuplicates( long dictPtr );
private static native String dict_getTilesInfo( long jniState, long dictPtr ); private static native String dict_getTilesInfo( long jniState, long dictPtr );
private static native boolean dict_getInfo( long jniState, long dictPtr, private static native DictInfo dict_getInfo( long jniState, long dictPtr,
boolean check, DictInfo info ); boolean check );
private static native String dict_getDesc( long dictPtr ); private static native String dict_getDesc( long dictPtr );
private static native long di_init( long jniState, long dictPtr, private static native long di_init( long jniState, long dictPtr,
PatDesc[] pats, int minLen, int maxLen ); PatDesc[] pats, int minLen, int maxLen );

View file

@ -527,12 +527,18 @@ makeObject( JNIEnv* env, const char* className, const char* initSig, ... )
return result; return result;
} }
jobject
makeObjectEmptyConst( JNIEnv* env, const char* className )
{
return makeObject( env, className, "()V" );
}
jobject jobject
makeJAddr( JNIEnv* env, const CommsAddrRec* addr ) makeJAddr( JNIEnv* env, const CommsAddrRec* addr )
{ {
jobject jaddr = NULL; jobject jaddr = NULL;
if ( NULL != addr ) { if ( NULL != addr ) {
jaddr = makeObject( env, PKG_PATH("jni/CommsAddrRec"), "()V" ); jaddr = makeObjectEmptyConst( env, PKG_PATH("jni/CommsAddrRec") );
setJAddrRec( env, jaddr, addr ); setJAddrRec( env, jaddr, addr );
} }
return jaddr; return jaddr;
@ -589,8 +595,8 @@ jobject
addrTypesToJ( JNIEnv* env, const CommsAddrRec* addr ) addrTypesToJ( JNIEnv* env, const CommsAddrRec* addr )
{ {
XP_ASSERT( !!addr ); XP_ASSERT( !!addr );
jobject result = makeObject( env, PKG_PATH("jni/CommsAddrRec$CommsConnTypeSet"), jobject result =
"()V" ); makeObjectEmptyConst( env, PKG_PATH("jni/CommsAddrRec$CommsConnTypeSet") );
XP_ASSERT( !!result ); XP_ASSERT( !!result );
jmethodID mid2 = getMethodID( env, result, "add", jmethodID mid2 = getMethodID( env, result, "add",
@ -712,7 +718,7 @@ intToJenumField( JNIEnv* env, jobject jobj, int val, const char* field,
jobject jenum = (*env)->GetObjectField( env, jobj, fid ); jobject jenum = (*env)->GetObjectField( env, jobj, fid );
if ( !jenum ) { /* won't exist in new object */ if ( !jenum ) { /* won't exist in new object */
jenum = makeObject( env, fieldSig, "()V" ); jenum = makeObjectEmptyConst( env, fieldSig );
XP_ASSERT( !!jenum ); XP_ASSERT( !!jenum );
(*env)->SetObjectField( env, jobj, fid, jenum ); (*env)->SetObjectField( env, jobj, fid, jenum );
} }

View file

@ -93,6 +93,7 @@ jmethodID getMethodID( JNIEnv* env, jobject obj, const char* proc,
const char* sig ); const char* sig );
jobject makeObject( JNIEnv* env, const char* className, const char* initSig, ... ); jobject makeObject( JNIEnv* env, const char* className, const char* initSig, ... );
jobject makeObjectEmptyConst( JNIEnv* env, const char* className );
jobject makeJAddr( JNIEnv* env, const CommsAddrRec* addr ); jobject makeJAddr( JNIEnv* env, const CommsAddrRec* addr );
jobject setJAddrRec( JNIEnv* env, jobject jaddr, const CommsAddrRec* addr ); jobject setJAddrRec( JNIEnv* env, jobject jaddr, const CommsAddrRec* addr );

View file

@ -184,7 +184,7 @@ makeDSI( AndDraw* draw, XWEnv xwe, int indx, const DrawScoreInfo* dsi )
jobject dsiobj = draw->jCache[indx]; jobject dsiobj = draw->jCache[indx];
if ( !dsiobj ) { if ( !dsiobj ) {
dsiobj = makeObject( env, PKG_PATH("jni/DrawScoreInfo"), "()V" ); dsiobj = makeObjectEmptyConst( env, PKG_PATH("jni/DrawScoreInfo") );
draw->jCache[indx] = (*env)->NewGlobalRef( env, dsiobj ); draw->jCache[indx] = (*env)->NewGlobalRef( env, dsiobj );
deleteLocalRef( env, dsiobj ); deleteLocalRef( env, dsiobj );

View file

@ -856,7 +856,7 @@ and_dutil_onInviteReceived( XW_DUtilCtxt* duc, XWEnv xwe, const NetLaunchInfo* n
DUTIL_CBK_HEADER( "onInviteReceived", "(L" PKG_PATH("NetLaunchInfo") ";)V" ); DUTIL_CBK_HEADER( "onInviteReceived", "(L" PKG_PATH("NetLaunchInfo") ";)V" );
/* Allocate a new NetLaunchInfo */ /* Allocate a new NetLaunchInfo */
jobject jnli = makeObject( env, PKG_PATH("NetLaunchInfo"), "()V" ); jobject jnli = makeObjectEmptyConst( env, PKG_PATH("NetLaunchInfo") );
XP_ASSERT( !!jnli ); XP_ASSERT( !!jnli );
setNLI( env, jnli, nli ); setNLI( env, jnli, nli );

View file

@ -830,10 +830,11 @@ Java_org_eehouse_android_xw4_jni_XwJNI_nli_1to_1stream
return result; return result;
} }
JNIEXPORT void JNICALL JNIEXPORT jobject JNICALL
Java_org_eehouse_android_xw4_jni_XwJNI_nli_1from_1stream Java_org_eehouse_android_xw4_jni_XwJNI_nli_1from_1stream
( JNIEnv* env, jclass C, jlong jniGlobalPtr, jobject jnli, jbyteArray jstream ) ( JNIEnv* env, jclass C, jlong jniGlobalPtr, jbyteArray jstream )
{ {
jobject jnli = NULL;
LOG_FUNC(); LOG_FUNC();
JNIGlobalState* globalState = (JNIGlobalState*)jniGlobalPtr; JNIGlobalState* globalState = (JNIGlobalState*)jniGlobalPtr;
#ifdef MEM_DEBUG #ifdef MEM_DEBUG
@ -844,6 +845,7 @@ Java_org_eehouse_android_xw4_jni_XwJNI_nli_1from_1stream
NetLaunchInfo nli = {0}; NetLaunchInfo nli = {0};
if ( nli_makeFromStream( &nli, stream ) ) { if ( nli_makeFromStream( &nli, stream ) ) {
jnli = makeObjectEmptyConst( env, PKG_PATH("NetLaunchInfo") );
setNLI( env, jnli, &nli ); setNLI( env, jnli, &nli );
} else { } else {
XP_LOGF( "%s: game_makeFromStream failed", __func__ ); XP_LOGF( "%s: game_makeFromStream failed", __func__ );
@ -851,18 +853,21 @@ Java_org_eehouse_android_xw4_jni_XwJNI_nli_1from_1stream
stream_destroy( stream, env ); stream_destroy( stream, env );
releaseMPool( globalState ); releaseMPool( globalState );
return jnli;
} }
JNIEXPORT void JNICALL JNIEXPORT jobject JNICALL
Java_org_eehouse_android_xw4_jni_XwJNI_comms_1getInitialAddr Java_org_eehouse_android_xw4_jni_XwJNI_comms_1getInitialAddr
( JNIEnv* env, jclass C, jobject jaddr, jstring jname, jint port ) ( JNIEnv* env, jclass C, jstring jname, jint port )
{ {
CommsAddrRec addr; CommsAddrRec addr;
const char* chars = (*env)->GetStringUTFChars( env, jname, NULL ); const char* chars = (*env)->GetStringUTFChars( env, jname, NULL );
comms_getInitialAddr( &addr, chars, port ); comms_getInitialAddr( &addr, chars, port );
(*env)->ReleaseStringUTFChars( env, jname, chars ); (*env)->ReleaseStringUTFChars( env, jname, chars );
jobject jaddr = makeObjectEmptyConst( env, PKG_PATH("jni/CommsAddrRec") );
setJAddrRec( env, jaddr, &addr ); setJAddrRec( env, jaddr, &addr );
return jaddr;
} }
JNIEXPORT jstring JNICALL JNIEXPORT jstring JNICALL
@ -1016,26 +1021,23 @@ Java_org_eehouse_android_xw4_jni_XwJNI_dict_1tilesToStr
return result; return result;
} }
JNIEXPORT jboolean JNICALL JNIEXPORT jobject JNICALL
Java_org_eehouse_android_xw4_jni_XwJNI_dict_1getInfo Java_org_eehouse_android_xw4_jni_XwJNI_dict_1getInfo
( JNIEnv* env, jclass C, jlong jniGlobalPtr, jlong dictPtr, ( JNIEnv* env, jclass C, jlong jniGlobalPtr, jlong dictPtr,
jboolean check, jobject jinfo ) jboolean check )
{ {
jboolean result = false; jobject result = NULL;
#ifdef MAP_THREAD_TO_ENV #ifdef MAP_THREAD_TO_ENV
JNIGlobalState* globalState = (JNIGlobalState*)jniGlobalPtr; JNIGlobalState* globalState = (JNIGlobalState*)jniGlobalPtr;
MAP_THREAD( &globalState->ti, env ); MAP_THREAD( &globalState->ti, env );
#endif #endif
DictionaryCtxt* dict = (DictionaryCtxt*)dictPtr; DictionaryCtxt* dict = (DictionaryCtxt*)dictPtr;
if ( NULL != dict ) { if ( NULL != dict ) {
if ( NULL != jinfo ) { result = makeObjectEmptyConst( env, PKG_PATH("jni/DictInfo") );
XP_LangCode code = dict_getLangCode( dict ); XP_LangCode code = dict_getLangCode( dict );
XP_ASSERT( 0 < code ); setInt( env, result, "langCode", code );
setInt( env, jinfo, "langCode", code ); setInt( env, result, "wordCount", dict_getWordCount( dict, env ) );
setInt( env, jinfo, "wordCount", dict_getWordCount( dict, env ) ); setString( env, result, "md5Sum", dict_getMd5Sum( dict ) );
setString( env, jinfo, "md5Sum", dict_getMd5Sum( dict ) );
}
result = true;
} }
return result; return result;
@ -1980,15 +1982,18 @@ Java_org_eehouse_android_xw4_jni_XwJNI_model_1getNumTilesInTray
return result; return result;
} }
JNIEXPORT void JNICALL JNIEXPORT jobject JNICALL
Java_org_eehouse_android_xw4_jni_XwJNI_model_1getPlayersLastScore Java_org_eehouse_android_xw4_jni_XwJNI_model_1getPlayersLastScore
( JNIEnv* env, jclass C, GamePtrType gamePtr, jint player, jobject jlmi ) ( JNIEnv* env, jclass C, GamePtrType gamePtr, jint player )
{ {
jobject jlmi;
XWJNI_START(); XWJNI_START();
XP_ASSERT( !!state->game.model ); XP_ASSERT( !!state->game.model );
LastMoveInfo lmi; LastMoveInfo lmi;
XP_Bool valid = model_getPlayersLastScore( state->game.model, env, XP_Bool valid = model_getPlayersLastScore( state->game.model, env,
player, &lmi ); player, &lmi );
jlmi = makeObjectEmptyConst( env, PKG_PATH("jni/LastMoveInfo") );
setBool( env, jlmi, "isValid", valid ); setBool( env, jlmi, "isValid", valid );
if ( valid ) { if ( valid ) {
setBool( env, jlmi, "inDuplicateMode", lmi.inDuplicateMode ); setBool( env, jlmi, "inDuplicateMode", lmi.inDuplicateMode );
@ -1999,6 +2004,7 @@ Java_org_eehouse_android_xw4_jni_XwJNI_model_1getPlayersLastScore
setString( env, jlmi, "word", lmi.word ); setString( env, jlmi, "word", lmi.word );
} }
XWJNI_END(); XWJNI_END();
return jlmi;
} }
JNIEXPORT jstring JNICALL JNIEXPORT jstring JNICALL
@ -2075,16 +2081,19 @@ Java_org_eehouse_android_xw4_jni_XwJNI_comms_1resetSame
XWJNI_END(); XWJNI_END();
} }
JNIEXPORT void JNICALL JNIEXPORT jobject JNICALL
Java_org_eehouse_android_xw4_jni_XwJNI_comms_1getAddr Java_org_eehouse_android_xw4_jni_XwJNI_comms_1getAddr
(JNIEnv* env, jclass C, GamePtrType gamePtr, jobject jaddr ) (JNIEnv* env, jclass C, GamePtrType gamePtr )
{ {
jobject jaddr;
XWJNI_START(); XWJNI_START();
XP_ASSERT( state->game.comms ); XP_ASSERT( state->game.comms );
CommsAddrRec addr; CommsAddrRec addr;
comms_getAddr( state->game.comms, &addr ); comms_getAddr( state->game.comms, &addr );
jaddr = makeObjectEmptyConst( env, PKG_PATH("jni/CommsAddrRec") );
setJAddrRec( env, jaddr, &addr ); setJAddrRec( env, jaddr, &addr );
XWJNI_END(); XWJNI_END();
return jaddr;
} }
JNIEXPORT jobjectArray JNICALL JNIEXPORT jobjectArray JNICALL