JNI:C调用Java

1.参考资料

  • 韦东山Java JNI视频
  • The Java™ Native Interface Programmer’s Guide and Specification

2.c 调用java的基本流程

在这里插入图片描述

3. C call Java static method(c调用java的静态方法)

  • Java代码
    • Java代码
      /*Hello.java*/
      
      public class Hello {
      	public static void main(String args[]){		//static method
      		System.out.println("Hello, world");
      	}
      	
      	public static void sayhello_to(String name){
      	}
      	
      	public static void sayhello_to(){
      	}
      }
      
    • 编译和生成signation
      • 编译Java
        javac Hello.java
      • 生成Signature
        javap -p -s Hello.class
        在这里插入图片描述
  • c代码
    • c 代码
      /*caller.c*/
      
      #include <stdio.h>
      #include <jni.h>
      
      /*init jvm*/
      jint create_vm(JavaVM** jvm, JNIEnv** env){
        	JavaVMInitArgs args; 
      	JavaVMOption options[1];  
      	args.version = JNI_VERSION_1_6;  
      	args.nOptions = 1;  
      	options[0].optionString = "-Djava.class.path=./";  
      	args.options = options;  
      	args.ignoreUnrecognized = JNI_FALSE;  
      	return JNI_CreateJavaVM(jvm, (void **)env, &args);  		
      }
      
      int main(int argc, char **argv)
      {
      	JavaVM* jvm;	//virtual machine
      	JNIEnv* env;	//environment
      	
      	jclass cls;		//class
      	int ret = 0;
      	
      	jmethodID mid;	//method
      	
      	/*1. create java virtual machine*/
      	if(create_vm(&jvm, &env)){
      		printf("can not create jvm\n");
      		return -1;
      	}
      	
      	/*2. get class*/
      	cls = (*env)->FindClass(env, "Hello");
      	if(cls == NULL){
      		printf("can not find Hello class\n");
      		ret = -1;
      		goto destroy;
      	}
      	
      	/*3. create object*/
      		//static method do not need to create object
      		
      	/*4. call method*/
      	/*4.1 get static method*/
      	mid = (*env)->GetStaticMethodID(env, cls, "main", "([Ljava/lang/String;)V");
      	if (mid == NULL) {
      		ret = -1;
      		printf("can not get method\n");
      		goto destroy;
      	}
      
      	/*4.2 create parameter*/
      		//main method don't have parameter
      	/*4.3 call static method*/	
      	(*env)->CallStaticVoidMethod(env, cls, mid, NULL);
      
      destroy:
      	(*jvm)->DestroyJavaVM(jvm);
      	return ret;
      }
      
      
    • 编译
      • gcc -I/usr/lib/jvm/java-7-openjdk-i386/include/ -o caller caller.c -L /usr/lib/jvm/java-7-openjdk-i386/jre/lib/i386/server/ -ljvm
      • -I : 表示<jni.h>头文件路径
      • -L : 表示链接库的路径
      • -ljvm : 表示要链接的库是libjvm.so
    • 执行
      • LD_LIBRARY_PATH=/usr/lib/jvm/java-7-openjdk-i386/jre/lib/i386/server/ ./caller
        在这里插入图片描述
      • LD_LIBRARY_PATH是Linux环境变量名,该环境变量主要用于指定查找共享库(动态链接库)时除了默认路径之外的其他路径。它在运行应用程序(已经被编译和链接完成)时指定动态库的路径。
      • 参考链接:LD_LIBRARY_PATH

4. C call Java non-static method(c调用java的非静态方法)

  • Java代码

    /*Hello.java*/
    
    public class Hello {
    	public static void main(String args[]){         //static method
    		System.out.println("Hello, world!");
    	}
    	
    	public int sayhello_to(String name){			//non-static method
    		System.out.println("Hello, "+name);
    		return 123;
    	}
    	
    	public static void sayhello_to(){
    	}
    }
    
  • c 代码

    /*caller.c*/
    
    #include <stdio.h>
    #include <jni.h>
    
    /*init jvm*/
    jint create_vm(JavaVM** jvm, JNIEnv** env){
      	JavaVMInitArgs args; 
    	JavaVMOption options[1];  
    	args.version = JNI_VERSION_1_6;  
    	args.nOptions = 1;  
    	options[0].optionString = "-Djava.class.path=./";  
    	args.options = options;  
    	args.ignoreUnrecognized = JNI_FALSE;  
    	return JNI_CreateJavaVM(jvm, (void **)env, &args);  		
    }
    
    int main(int argc, char **argv)
    {
    	JavaVM* jvm;	//virtual machine
    	JNIEnv* env;	//environment
    	
    	jclass cls;
    	int ret = 0;
    	
    	jmethodID mid;
    	jmethodID cid;
    	
    	jobject jobj;
    	jstring jstr;
    
    	int r;
    	
    	/* 1. create java virtual machine*/
    	if(create_vm(&jvm, &env)){
    		printf("can not create jvm\n");
    		return -1;
    	}
    	
    	/* 2. get class*/
    	cls = (*env)->FindClass(env, "Hello");
    	if(cls == NULL){
    		printf("can not find Hello class\n");
    		ret = -1;
    		goto destroy;
    	}
    	
    	/* 3. create object */
    	/* 3.1 get constructor method */
    	/* Get the method ID for the String constructor */
    	cid = (*env)->GetMethodID(env, cls,	"<init>", "()V");
    	if (cid == NULL) {
    		ret = -1;
    		printf("can not get constructor method");
    		goto destroy;
    	}	
    		
     	/* 3.2 NewObject */
    	jobj = (*env)->NewObject(env, cls, cid);
    	if (jobj == NULL) {
    		ret = -1;
    		printf("can not create object");
    		goto destroy;
    	}	
    	
    	 		
    	/* 4. call public method*/
    	/* 4.1 get public method ID*/
    	mid = (*env)->GetMethodID(env, cls, "sayhello_to","(Ljava/lang/String;)I");
    	if (mid == NULL) {
    		ret = -1;
    		printf("can not get method\n");
    		goto destroy;
    	}	
    	
    	/*4.2 create parameter for public method*/
    	jstr = (*env)->NewStringUTF(env, "girl");
    	
    	/*4.3 call public method*/	
    	r = (*env)->CallIntMethod(env, jobj, mid, jstr);
    	printf("ret = %d\n", r);
    
    
    destroy:
    	(*jvm)->DestroyJavaVM(jvm);
    	return ret;
    }
    
    
  • 编译和执行

    • java和c的编译和执行方法和上面一样
      在这里插入图片描述

5. C set Java field(c设置java的属性)

  • Java代码

    /*Hello.java*/
    
    public class Hello {
    	private String name;	//private
    	private int age;		//private
    	
    	public static void main(String args[]){		//static method
    		System.out.println("Hello, world!");
    	}
    	
    	public int sayhello_to(String name){		//non-static method
    		System.out.println("Hello, "+name+"! I am "+this.name+", "+age+" years old.");
    		return 123;
    	}
    	
    	public static void sayhello_to(){
    	}
    }
    
  • c代码

    /* caller.c */
    
    #include <stdio.h>
    #include <jni.h>
    
    /*init jvm*/
    jint create_vm(JavaVM** jvm, JNIEnv** env){
      	JavaVMInitArgs args; 
    	JavaVMOption options[1];  
    	args.version = JNI_VERSION_1_6;  
    	args.nOptions = 1;  
    	options[0].optionString = "-Djava.class.path=./";  
    	args.options = options;  
    	args.ignoreUnrecognized = JNI_FALSE;  
    	return JNI_CreateJavaVM(jvm, (void **)env, &args);  
    }
    
    int main(int argc, char **argv)
    {
    	JavaVM* jvm;	//virtual machine
    	JNIEnv* env;	//environment
    	
    	jclass cls;
    	int ret = 0;
    	
    	jmethodID mid;
    	jmethodID cid;
    	
    	jobject jobj;
    	jstring jstr;
    	
    	jfieldID nameID;
    	jfieldID ageID;
    
    	int r;
    	
    	/* 1. create java virtual machine*/
    	if(create_vm(&jvm, &env)){
    		printf("can not create jvm\n");
    		return -1;
    	}
    	
    	/* 2. get class*/
    	cls = (*env)->FindClass(env, "Hello");
    	if(cls == NULL){
    		printf("can not find Hello class\n");
    		ret = -1;
    		goto destroy;
    	}
    	
    	/* 3. create object */
    	/* 3.1 get constructor method */
    	/* Get the method ID for the String constructor */
    	cid = (*env)->GetMethodID(env, cls,	"<init>", "()V");
    	if (cid == NULL) {
    		ret = -1;
    		printf("can not get constructor method");
    		goto destroy;
    	}	
    		
     	/* 3.2 NewObject */
    	jobj = (*env)->NewObject(env, cls, cid);
    	if (jobj == NULL) {
    		ret = -1;
    		printf("can not create object");
    		goto destroy;
    	}	
    	
    	/* 4. get/set field   */
    	/* 4.1. get field id  */
    	/* 4.2. get/set field */
    
    	/* name */
    	nameID = (*env)->GetFieldID(env, cls, "name", "Ljava/lang/String;");
    	if (nameID == NULL) {
    		ret = -1;
    		printf("can not get field name");
    		goto destroy;
    	}
    	jstr = (*env)->NewStringUTF(env, "Bill");
    	(*env)->SetObjectField(env, jobj, nameID, jstr);
    
    	/* age */
    	ageID = (*env)->GetFieldID(env, cls, "age", "I");
    	if (ageID == NULL) {
    		ret = -1;
    		printf("can not get field age");
    		goto destroy;
    	}
    	(*env)->SetIntField(env, jobj, ageID, 10);
    
    	 		
    	/* 5. call public method */
    	/* 5.1 get public method ID */
    	mid = (*env)->GetMethodID(env, cls, "sayhello_to","(Ljava/lang/String;)I");
    	if (mid == NULL) {
    		ret = -1;
    		printf("can not get method\n");
    		goto destroy;
    	}	
    	
    	/* 5.2 create parameter for public method */
    	jstr = (*env)->NewStringUTF(env, "girl");
    	
    	/* 5.3 call public method */	
    	r = (*env)->CallIntMethod(env, jobj, mid, jstr);
    	printf("ret = %d\n", r);
    
    destroy:
    	(*jvm)->DestroyJavaVM(jvm);
    	return ret;
    }
    
    
  • 编译和执行
    在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值