一 定义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