Utiliser JNI au lieu de la JNA à appeler du code natif?
JNA semble un peu juste plus facile à utiliser pour appeler du code natif par rapport à la JNI. Dans ce cas, voudriez-vous utiliser JNI plus de la JNA?
- Essayez également BridJ.
- L'un des facteurs importants que nous avons choisi JNA sur JNI, est que la JNA ne nécessite pas de modifications à nos bibliothèques natives. Ayant pour personnaliser les bibliothèques natives juste pour être en mesure de travailler avec Java a été un grand PAS pour nous.
Vous devez vous connecter pour publier un commentaire.
Ce sont ces problèmes que j'ai rencontré. Il existe peut-être plus. Mais en général, le rendement n'est pas très différent entre la jna et de la jni, donc où que vous pouvez utiliser JNA, l'utiliser.
MODIFIER
Cette réponse semble être très populaire. Voici donc quelques ajouts:
Donc, je persiste à croire que, dans la mesure du possible, il est préférable d'utiliser JNA ou BridJ, et de revenir à la jni si la performance est critique, parce que si vous avez besoin d'appeler des fonctions natives fréquemment, de gain de performance est notable.
JNIEXPORT
fonctions. Je suis actuellement en train d'explorer JavaCpp en option, qui utilise JNI, mais je ne pense pas que la vanille JNI prend en charge cette. Est-il possible d'appeler des fonctions membres C++ à l'aide de la vanille JNI que je suis dominant?Il est difficile de répondre à cette question générique. Je suppose que la différence la plus évidente est que, avec JNI, la conversion de type est mis en œuvre sur le natif du côté de l'Java/native de la frontière, alors qu'avec la JNA, la conversion de type est implémenté en Java. Si vous vous sentez déjà très à l'aise avec la programmation en C et à mettre en œuvre du code natif vous-même, je suppose que la JNI de ne pas sembler trop complexe. Si vous êtes un programmeur Java, et seulement besoin d'invoquer un tiers à la bibliothèque native, à l'aide de la " JNA " est probablement le plus simple chemin pour éviter peut-être pas si évident problèmes avec JNI.
Bien que je n'ai jamais comparé les différences, je serait à cause de la conception, à moins de supposer que la conversion de type avec JNA dans certaines situations sera moins bon qu'avec JNI. Par exemple lors du passage de tableaux, JNA va les convertir à partir de Java natif au début de chaque appel de fonction et à la fin de l'appel de la fonction. Avec JNI, vous pouvez contrôler vous-même quand une native "vue" du tableau est généré, potentiellement seulement à la création d'une vue d'une partie de la matrice, à garder la vue sur plusieurs appels de fonction et à la fin de dégagement de la vue et de décider si vous souhaitez conserver les modifications (ce qui pourrait nécessiter de copier les données) ou d'annuler les modifications (pas de copie requis). Je sais que vous pouvez utiliser un natif de tableau dans les appels de fonction avec la JNA à l'aide de la Mémoire de la classe, mais il faudra aussi que la mémoire de la copie, ce qui peut être inutile avec JNI. La différence peut ne pas être pertinent, mais si votre objectif est d'augmenter la performance de l'application par la mise en œuvre des parties de code natif, à l'aide d'un pire exécution de pont de la technologie ne semble pas être le choix le plus évident.
C'est seulement ce que je peux trouver sur le dessus de ma tête, mais je ne suis pas un gros utilisateur de soit. Il semble aussi que vous pourriez éviter la JNA si vous voulez une meilleure interface que celle qu'ils fournissent, mais vous pourriez le code de autour de que en java.
Par la façon dont, dans l'un de nos projets, nous en avons gardé un très petit JNI pied d'impression. Nous avons utilisé des tampons de protocole pour la représentation de nos objets du domaine et a donc eu une seule fonction native de pont de Java et de C (puis, bien sûr, que la fonction C pourrait appeler un tas d'autres fonctions).
Ce n'est pas une réponse directe et je n'ai aucune expérience avec la JNA, mais, quand je regarde les Les projets Utilisant la JNA et voir des noms comme SVNKit, IntelliJ IDEA, NetBeans IDE, etc, je suis tendance à croire que c'est un assez décent de la bibliothèque.
En fait, je crois vraiment que je l'aurais utilisé JNA à la place de la JNI quand j'ai dû, comme il semble en effet plus simple que la JNI (qui a un ennuyeux processus de développement). Trop mauvais, JNA n'est pas sorti à ce moment.
Si vous voulez JNI performance, mais sont rebutés par sa complexité, vous pouvez envisager d'utiliser des outils permettant de générer JNI liaisons automatiquement. Par exemple, JANET (avertissement: je l'ai écrit) vous permet de mixer de Java et de C++ code dans un seul fichier source, et, par exemple, de faire des appels à partir de C++ à Java en utilisant la norme de la syntaxe Java. Par exemple, voici comment vous pouvez imprimer une chaîne C de la norme Java de sortie:
JANET se traduit alors par la backtick-embedded Java dans le JNI appels.
J'ai fait des simples repères avec JNI et de la JNA.
Comme déjà souligné, la JNA est pour des raisons de commodité. Vous n'avez pas besoin de compiler ou d'écrire du code natif lors de l'utilisation de JNA. JNA natif du chargeur de bibliothèque est également l'un des meilleurs/la plus facile à utiliser que j'ai jamais vu. Malheureusement, vous ne pouvez pas l'utiliser pour JNI, il me semble. (C'est pourquoi j'ai écrit une alternative au Système.loadLibrary() qui utilise le chemin d'accès de la convention de la JNA et prend en charge transparente chargement du chemin de classe (c'est à dire des pots).)
La performance de la JNA cependant, peut être bien pire que celle de la JNI. J'ai fait un très simple test appelé un simple natif entier incrément de la fonction "retour arg + 1;". Repères fait avec jmh a montré que la JNI les appels à cette fonction sont 15 fois plus rapide que la JNA.
Plus "complexe" exemple où la fonction native résume un tableau d'entiers de 4 valeurs ont montré que la JNI de performance est 3 fois plus rapide que la JNA. La réduction de l'avantage est probablement à cause de la façon dont vous accédez à des tableaux dans la JNI: mon exemple créé des choses et publié de nouveau lors de chaque opération de sommation.
Code et les résultats de test peuvent être trouvés sur github.
J'ai étudié la JNI et de la JNA de comparer la performance parce que nous avons dû choisir l'un d'eux d'appeler une dll dans le projet et nous avons eu une vraie contrainte de temps. Les résultats ont montré que la JNI a de meilleures performances que les JNA(environ 40 fois). Peut-être il y a un truc pour une meilleure performance dans la JNA, mais il est très lent pour un exemple simple.
À moins que je me manque quelque chose, n'est-ce pas la principale différence entre la JNA vs JNI qu'avec la JNA vous ne pouvez pas appeler du code Java à partir d'natif (C) code?