Maison > Tutoriel système > Linux > le corps du texte

Comment utiliser JNI pour appeler du code C/C++ sous Linux

PHPz
Libérer: 2024-02-13 15:30:04
avant
1048 Les gens l'ont consulté

Avez-vous déjà pensé à utiliser des fonctions C ou C++ dans un programme Java ? Savez-vous ce qu'est JNI et comment il vous permet d'implémenter une programmation multilingue sous Linux ? Si ces questions vous intéressent, alors cet article est fait pour vous. Cet article présentera les concepts de base de JNI, ainsi que les étapes et exemples d'utilisation de JNI pour appeler du code C/C++ sous Linux.

Comment utiliser JNI pour appeler du code C/C++ sous Linux

Définir une classe Java — Bonjour la classe

 public class Hello 
 { 
  static 
  { 
   try 
   { 
 // 此处即为本地方法所在链接库名
    System.loadLibrary("hello"); 
   } 
   catch(UnsatisfiedLinkError e) 
   { 
    System.err.println( "Cannot load hello library:\n " + 
                                e.toString() ); 
   } 
  } 
  public Hello() 
  { 
  } 
 // 声明的本地方法
   public native void SayHello(String strName); 
 }
Copier après la connexion

Il y a deux choses à noter ici :

Tout d'abord : Écrivez une déclaration de méthode native pour chaque méthode native que vous souhaitez utiliser, il vous suffit de préciser le mot-clé natif, comme ceci :

public native void SayHello(String strName);
Copier après la connexion

Deuxième : la bibliothèque de codes locale doit être chargée explicitement. Nous devons charger cette bibliothèque dans le bloc statique de la classe (la bibliothèque statique sera appelée lorsque la classe sera chargée)

Modifions maintenant hello.java pour générer le fichier hello.class.

Générer une bibliothèque de liens locaux

Pour générer le fichier d'en-tête de l'interface locale Java pour la classe définie ci-dessus, vous devez utiliser javah. La fonction javah du compilateur Java générera les déclarations nécessaires basées sur la classe Hello. Cette commande générera le fichier Hello.h

.

Le contenu du fichier Hello.h généré est le suivant :

 #include  
 /* Header for class Hello */ 
 #ifndef _Included_Hello 
 #define _Included_Hello 
 #ifdef __cplusplus 
 extern "C" { 
 #endif 
 /* 
 * Class:     Hello 
 * Method:    SayHello 
 * Signature: (Ljava/lang/String;)V 
 */ 
 JNIEXPORT void JNICALL Java_Hello_SayHello 
  (JNIEnv *, jobject, jstring); 
 #ifdef __cplusplus 
 } 
 #endif 
 #endif
Copier après la connexion

Créez un fichier CPP Hello.cpp dans le même chemin que Hello.h

Le contenu est le suivant :

#include "Hello.h"
 #include  
 // 与 Hello.h 中函数声明相同
 JNIEXPORT void JNICALL Java_Hello_SayHello  (JNIEnv * env, jobject arg, jstring instring) 
 { 
   // 从 instring 字符串取得指向字符串 UTF 编码的指针
 const jbyte *str = 
        (const jbyte *)env->GetStringUTFChars( instring, JNI_FALSE ); 
    printf("Hello,%s\n",str); 
  // 通知虚拟机本地代码不再需要通过 str 访问 Java 字符串。
    env->ReleaseStringUTFChars( instring, (const char *)str ); 
    return; 
 }
Copier après la connexion

Il y a trois paramètres ici. Parlons de l'utilisation des paramètres :

(1) Tous les appels JNI utilisent des pointeurs de type JNIEnv * Il est d'usage de définir cette variable comme evn dans le fichier CPP, qui est le premier paramètre de toute méthode locale. Le pointeur env pointe vers une table de pointeurs de fonctions et les fonctions qu'elle contient sont directement accessibles à l'aide de l'opérateur "->" dans VC.
(2) jobject pointe vers un handle vers l'objet Java LocalFunction instancié dans ce code Java, qui est équivalent au pointeur this.
(3) Le troisième paramètre est le paramètre transmis par le programme Java dans l'appel local. Dans cet exemple, il n'y a qu'un seul paramètre String. Pour les paramètres de chaîne, étant donné que les chaînes Java ne peuvent pas être lues directement dans le code natif, elles doivent être converties en chaînes C/C++ ou Unicode.

Compilez et générez des bibliothèques partagées.

Lorsque vous utilisez GCC, vous devez indiquer au compilateur où trouver le fichier de support pour cette méthode native Java, et indiquer explicitement au compilateur de générer du code indépendant de la position, qui est compilé comme suit dans mon environnement :

gcc -I/home/jbuilder/jdk1.3.1/include 
    -I/home/jbuilder/jdk1.3.1/include/linux -fPIC -c Hello.c
Copier après la connexion

Générer Hello.o

gcc -shared -Wl,-soname,libhello.so -o libhello.so Hello.o
Copier après la connexion

Générer libhello.so (c'est le format de nom de fichier de la bibliothèque de liens dynamiques sous Linux, tout comme le suffixe du fichier .dll sous Windows)

Enfin, informez l'éditeur de liens dynamique du chemin d'accès à ce fichier partagé.

export LD_LIBRARY_PATH=`pwd`:$LD_LIBRARY_PATH
Copier après la connexion

Écrire un programme Java simple pour tester notre méthode native

Enregistrez le code source suivant sous A.java :

 import Hello; 
 import java.util.*; 
 public class A 
 { 
  public static void main(String argv[]) 
  { 
   A a = new A(); 
  } 
  public A() 
  { 
   Hello h = new Hello(); 
   // 调用本地方法
   h.SayHello("Hello world");    
  } 
 }
Copier après la connexion

Utilisez javac pour compiler A.java et générer A.class
En utilisant Java A, tout comme en exécutant un programme Java normal, nous verrons Hello World apparaître à l'écran.
Grâce à cet article, vous devriez avoir une compréhension préliminaire de JNI et comment utiliser JNI pour appeler du code C/C++ sous Linux. JNI est un outil puissant et flexible qui vous permet de tirer parti du C/C++ dans un programme Java, ou de profiter de Java dans un programme C/C++. Bien entendu, JNI présente également quelques défauts, tels que des pertes de performances, des fuites de mémoire, la gestion des erreurs, etc. Par conséquent, lorsque vous utilisez JNI, vous devez faire attention à certains détails et spécifications pour garantir l'exactitude et la sécurité du code. J'espère que cet article pourra vous être utile. Si vous avez des questions ou des suggestions, veuillez laisser un message dans la zone de commentaires.

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

source:lxlinux.net
Déclaration de ce site Web
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn
Tutoriels populaires
Plus>
Derniers téléchargements
Plus>
effets Web
Code source du site Web
Matériel du site Web
Modèle frontal
À propos de nous Clause de non-responsabilité Sitemap
Site Web PHP chinois:Formation PHP en ligne sur le bien-être public,Aidez les apprenants PHP à grandir rapidement!