2011-01-30 16 views

Respuesta

1

Ver here:

un código de ejemplo para llamar a un constructor de cadena:

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; 
} 
+3

¡Bien! Gracias ... pero ¿cómo creo un HashMap ? – AOO

12

Aquí está el código, tendrá que modificar para trabajar

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); 
+1

¿No debería eliminar la referencia local a hashMap? – miguelSantirso

+1

Para futuros lectores, asegúrese de '' 'env-> DeleteLocalRef (mapClass)' '' también. – Constantin

2

Para mí encontré que la firma del método "put" debe ser diferente de la enumerada en el ejemplo anterior. es decir,

jmethodID put = env->GetMethodID(mapClass, "put", "(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;"); 
0

También se pueden considerar alternativas al uso directo de JNI, p. ej. herramientas que pueden generar código JNI para usted. Por ejemplo, JANET (disclaimer: Me lo escribió) permite incrustar el código de Java en los métodos nativos, por lo que la creación y el uso de un mapa hash es tan simple como:

... (C++ code) 
`Map map = new HashMap();` // embedded Java 
... (C++ code) 
... const char* foo = "foo"; 
`map.put(#$(foo), 50);` // ["foo" -> 50] 

las declaraciones de respaldo Ticked se traducen por Código JANET a JNI, por lo que nunca tendrá que preocuparse por las firmas, el manejo de las referencias, el manejo de excepciones, etc., pero aún obtendrá el rendimiento de JNI.