2010-06-22 4 views
4

J'ai une couche C++ qui parle à un db, cette couche C++ fait un nouveau SomeObject() et le renvoie à java.jni et en utilisant C++ new'ed objets en java

Quand est-il sécuritaire de dire supprimer SomeObject via mon appel jni propre. Puis-je supprimer dès que java a l'objet retourné ou dois-je copier l'objet puis le supprimer?

+1

Comment renvoyer un objet C++ directement à Java? Ne devez-vous pas utiliser l'environnement JNI pour instancier l'objet Java approprié? – Daff

+0

Ouais, c'est un peu ce que je pensais, je suis dans un nouvel endroit et je regarde ce code et je ne suis pas sûr que toutes les pièces sont en place. – arinte

Répondre

9

Comme Daff a écrit, vous ne pouvez pas « retourner un objet C++ à Java, » mais ce que vous pouvez faire est de retourner l'adresse de l'objet, comme une longue:

jlong obj_ptr = reinterpret_cast<jlong>(&obj); 

Vous devez vous assurer quelque part dans un en-tête racine que la taille de jlong ​​est suffisante pour contenir des pointeurs (cela devrait généralement l'être, car un Java long a une largeur de 64 bits). J'utilise assert statique Boost pour vérifier ceci:

#include <boost/static_assert.hpp> 
BOOST_STATIC_ASSERT(sizeof(jlong)>=sizeof(void *)); 

L'objet du C doit vivre aussi longtemps qu'il (ou ses données) est nécessaire, que ce soit en Java ou C++ - de toute façon, il ne peut pas être supprimé par Java directement. Lorsque vous déterminez que vous pouvez le supprimer en toute sécurité, vous pouvez effectuer un autre appel JNI à partir de Java, en transmettant la valeur longue, l'afficher au pointeur approprié avec reinterpret_cast<SomeObject *>(the_jlong_value) et le supprimer. Bien sûr, vous devez le supprimer manuellement, la JVM ignore totalement son existence, et toutes les mises en garde de la gestion manuelle de la mémoire s'appliquent ...

+4

n'en ai plus besoin J'ai quitté la terrible compagnie où j'avais besoin de faire ça. – arinte

+0

Dans l'exemple ci-dessus, obj doit être déclaré dans une portée globale. Sinon, il peut retourner l'adresse de la pile, ce qui est invalide dès que la fonction contenante retourne –

+0

Vous ne voulez pas dire "déclaré dans une portée globale". Vous voulez dire "alloué sur le tas et pas sur la pile." –