Come si crea un oggetto HashMap in JNI?JNI: Crea HashMap
risposta
Vedi here:
Alcuni codice di esempio per chiamare un costruttore String:
jstring
MyNewString(JNIEnv *env, jchar *chars, jint len)
{
jclass stringClass;
jmethodID cid;
jcharArray elemArr;
jstring result;
stringClass = (*env)->FindClass(env, "java/lang/String");
if (stringClass == NULL) {
return NULL; /* exception thrown */
}
/* Get the method ID for the String(char[]) constructor */
cid = (*env)->GetMethodID(env, stringClass,
"<init>", "([C)V");
if (cid == NULL) {
return NULL; /* exception thrown */
}
/* Create a char[] that holds the string characters */
elemArr = (*env)->NewCharArray(env, len);
if (elemArr == NULL) {
return NULL; /* exception thrown */
}
(*env)->SetCharArrayRegion(env, elemArr, 0, len, chars);
/* Construct a java.lang.String object */
result = (*env)->NewObject(env, stringClass, cid, elemArr);
/* Free local references */
(*env)->DeleteLocalRef(env, elemArr);
(*env)->DeleteLocalRef(env, stringClass);
return result;
}
Ecco il codice, è necessario modificare per lavorare
jclass mapClass = (*env)->FindClass(env, "java/util/HashMap");
if(mapClass == NULL)
{
return NULL;
}
jsize map_len = 1;
jmethodID init = (*env)->GetMethodID(env, mapClass, "<init>", "(I)V");
jobject hashMap = (*env)->NewObject(env, mapClass, init, map_len);
jmethodID put = (*env)->GetMethodID(env, mapClass, "put",
"(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;");
while(...)
{
jint key = ...;
size_t sz = t->count;
jbyteArray dd = (*env)->NewByteArray(env, sz);
for(i = 0; i < sz; i++)
{
(*env)->SetByteArrayRegion(env, dd, i, 1, *data++);
}
(*env)->CallObjectMethod(env, hashMap, put, key, dd);
(*env)->DeleteLocalRef(env, key);
(*env)->DeleteLocalRef(env, dd);
}
(*env)->DeleteLocalRef(env, hashMap);
(*env)->DeleteLocalRef(env, mapClass);
Non dovresti eliminare il riferimento locale a hashMap? – miguelSantirso
Per i futuri lettori, assicuratevi di '' 'env-> DeleteLocalRef (mapClass)' '' pure. – Constantin
Per me ho scoperto che la firma del metodo "put" doveva essere diversa da quella elencata nell'esempio sopra. ovvero
jmethodID put = env->GetMethodID(mapClass, "put", "(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;");
Si può anche considerare alternative all'utilizzo diretto di JNI - ad es. strumenti in grado di generare codice JNI per te. Ad esempio, JANET (disclaimer: ho scritto) permette di incorporare codice Java nei vostri metodi nativi, in modo da creare e usare una mappa di hash è poi così semplice come:
... (C++ code)
`Map map = new HashMap();` // embedded Java
... (C++ code)
... const char* foo = "foo";
`map.put(#$(foo), 50);` // ["foo" -> 50]
le dichiarazioni di back-segno di spunta vengono tradotti da JANET to JNI code, quindi non dovrai mai preoccuparti delle firme, della gestione dei riferimenti, della gestione delle eccezioni, ecc., Ma ottieni comunque le prestazioni di JNI.
Ok! Grazie ... ma come faccio a creare una HashMap? –
AOO