les ressources allouées à l'association C avec des objets java - Java JNI?
-
22-09-2019 - |
Question
Je veux allouer de la mémoire en C et le garder associé à une instance d'objet java, comme ceci:
void configure(JNIEnv *object, jobject obj, ....) {
char *buf = new char[1024];
// associated <buf> with <obj> somehow
}
Et puis libérer plus tard la mémoire lorsque l'objet java se ramasse-miettes -. Je pouvais le faire en appelant une fonction JNI de la finaliser () méthode de l'objet java
La question est, comment puis-je associer un pointeur C avec l'objet java? Gardez un long dans l'objet et jeter le pointeur sur long ? Y at-il une meilleure façon?
La solution
En général, si vous voulez transférer un pointeur de C à Java, il est recommandé d'utiliser long
afin qu'il y ait suffisamment de bits pour maintenir la valeur du pointeur dans le cas où la plate-forme est de 64 bits.
Alors, jetez un oeil à ByteBuffer.allocateDirect()
qui crée une instance de ByteBuffer
dont la mémoire peut être partagée avec C. vous pouvez attribuer un tel ByteBuffer
direct depuis le côté Java passe alors comme un jobject
à une fonction JNI et à l'intérieur de cette fonction JNI utilisez-vous fonction GetDirectBufferAddress
.
Une autre façon est d'envelopper une zone native de la mémoire avec le NewDirectByteBuffer
fonction JNI du côté natif. Il vous donne un jobject
vous passez vers le côté Java (attention aux références locales et globales). Faites attention au fait qu'une fois que la ByteBuffer
directe qui enveloppe la mémoire native a été créé, vous êtes toujours responsable de la gestion de la mémoire native: à un moment donné, vous devrez appeler delete buf;
dans votre code natif, Java ne le fera pas pour vous.
Autres conseils
Java ne possède pas de concept de pointeur natif, donc le stockage comme une longue est la seule option réelle. Mais vous ne devriez pas compter sur finalize
pour libérer le pointeur; la méthode finalize est peu fiable comme moyen de nettoyage des ressources. Voir cette question pour plus de détails.