NDK06_JNI实现native方法,获取类普通成员、类静态成员

NDK开发汇总

一 定义Native方法

public class JniMain {
	
	public String key = "key";
	
	public static int count = 9;
	
	

	
	public native static String getStringFromC();
	
	public native String getStringFromC2();
	
	public native String accessField();
	
	public native String accessStaticField();
	
	}

二 生成h文件

/* DO NOT EDIT THIS FILE - it is machine generated */
#include "jni.h"
/* Header for class JniMain */

#ifndef _Included_JniMain
#define _Included_JniMain
#ifdef __cplusplus
extern "C" {
#endif
/*
 * Class:     JniMain
 * Method:    getStringFromC
 * Signature: ()Ljava/lang/String;
 */
JNIEXPORT jstring JNICALL Java_JniMain_getStringFromC
  (JNIEnv *, jclass);

/*
 * Class:     JniMain
 * Method:    getStringFromC2
 * Signature: ()Ljava/lang/String;
 */
JNIEXPORT jstring JNICALL Java_JniMain_getStringFromC2
  (JNIEnv *, jobject);

/*
 * Class:     JniMain
 * Method:    accessField
 * Signature: ()Ljava/lang/String;
 */
JNIEXPORT jstring JNICALL Java_JniMain_accessField
  (JNIEnv *, jobject);

/*
 * Class:     JniMain
 * Method:    accessStaticFiel
 * Signature: ()Ljava/lang/String;
 */
JNIEXPORT jstring JNICALL Java_JniMain_accessStaticField
  (JNIEnv *, jobject);

#ifdef __cplusplus
}
#endif
#endif

三 class文件中命令行查看方法的签名

命令: javap -s 目标类.class

 C:\rj\java_workspace\Lsn6\bin> javap -s JniMain.class
Compiled from "JniMain.java"
public class JniMain {
  public java.lang.String key;
    descriptor: Ljava/lang/String;
  public static int count;
    descriptor: I
  static {};
    descriptor: ()V

  public JniMain();
    descriptor: ()V

  public static native java.lang.String getStringFromC();
    descriptor: ()Ljava/lang/String;

  public native java.lang.String getStringFromC2();
    descriptor: ()Ljava/lang/String;

  public native java.lang.String accessField();
    descriptor: ()Ljava/lang/String;

  public native java.lang.String accessStaticField();
    descriptor: ()Ljava/lang/String;

  public static void main(java.lang.String[]);
    descriptor: ([Ljava/lang/String;)V
}

四 c中实现h文件的具体方法,生产dll库

#include "stdafx.h"
#include <stdio.h>
#include "JniMain.h"
#include <string.h>
// 静态方法 jclass
JNIEXPORT jstring JNICALL Java_JniMain_getStringFromC
(JNIEnv * env, jclass jclz) {
	return (*env)->NewStringUTF(env, "C string");
}

// 非静态方法 jobject
JNIEXPORT jstring JNICALL Java_JniMain_getStringFromC2
(JNIEnv * env, jobject jobj) {
	return (*env)->NewStringUTF(env, "C String 2");
}

//访问非静态域 
JNIEXPORT jstring JNICALL Java_JniMain_accessField
(JNIEnv * env, jobject jobj) {
	//jclass
	jclass jclz = (*env)->GetObjectClass(env, jobj);

	// fieldId 属性名称,属性签名
	jfieldID fid = (*env)->GetFieldID(env, jclz, "key", "Ljava/lang/String;");
	//key 
	
	//得到key 对应的值,GetXXXField
	jstring jstr = (*env)->GetObjectField(env, jobj, fid);

	//jni -> C
	char * c_str = (*env)->GetStringUTFChars(env, jstr, NULL);


	char text[30] = "Ray";
	// 生成新的字符串 Ray key
	strcat(text, c_str);

	// C -> jni
	jstring new_str = (*env)->NewStringUTF(env, text);

	//setXXXField
	(*env)->SetObjectField(env, jobj, fid, new_str);
	(*env)->ReleaseStringChars(env, new_str, c_str);

	return new_str;
}

JNIEXPORT jstring JNICALL Java_JniMain_accessStaticField
(JNIEnv * env, jobject jobj) {
	// jclass
	jclass jclz = (*env)->GetObjectClass(env, jobj);

	// fieldId 属性名称,属性签名
	jfieldID fid = (*env)->GetStaticFieldID(env, jclz, "count", "I");


	if (fid == NULL)
	{
		printf("fid is null");
	}
	jint count = (*env)->GetStaticIntField(env, jclz, fid);
	count++;

	(*env)->SetStaticIntField(env, jclz, fid, count);

	return (*env)->NewStringUTF(env, "accessStaticField");
}

五 java项目中集成dll库,调用方法

public class JniMain {
	
	public String key = "key";
	
	public static int count = 9;
	
	

	
	public native static String getStringFromC();
	
	public native String getStringFromC2();
	
	public native String accessField();
	
	public native String accessStaticField();
	
	
	
	static {
		System.loadLibrary("lsn7");
	}
	
	public static void main(String[] rags) {
		System.out.print(getStringFromC());
		
		
		  System.out.println(getStringFromC());
	        
	        JniMain jniMain = new JniMain();
	        System.out.println(jniMain.getStringFromC2()); 
	        
	        System.out.println("change before key: " + jniMain.key);
	        jniMain.accessField();
	        System.out.println("after change, Key:  " + jniMain.key);
	        
	        System.out.println("change before count: " + count);
	        jniMain.accessStaticField();
	        System.out.println("change after count: " + count);
	}
	
}

输出结果:
C stringC string
C String 2
change before key: key
after change, Key: Raykey
change before count: 9
change after count: 10

六 Demo
lsn6_1.zip

发布了269 篇原创文章 · 获赞 123 · 访问量 16万+

猜你喜欢

转载自blog.csdn.net/baopengjian/article/details/104870333