前言:相信你看了我上篇的《JNI开发流程》博客,已经对JNI的开发有所了解,相信你也注意到了一点,java中我使用的是非静态方法生成的头文件,ok今天,来说一下静态和非静态的两种头文件的区别!
------------分割线--------------
1、java项目中JniTest.java中添加代码:
//非静态的
public native String getCString();
//静态的
public native static String getCStringStatic();
2、用javah在cmd中生成:
3、刷新eclipse可有看到生成com_fly_TestJni.h,直接打开看里面的重要代码:
可以看到 参数区别在于 第二个参数
(1) 静态的参数 (JNIEnv *, jclass);
jclass是传入对象的对应的class 在本例中就是TestJni.class
(2)非静态的参数 (JNIEnv *, jobject);
jobject是传入对象的对应实力 在本例中就是TestJni这个实例
4、在01.c中代码:
#include"com_fly_TestJni.h"
//非静态的
JNIEXPORT jstring JNICALL Java_com_fly_TestJni_getCString
(JNIEnv *env, jobject jobj){
char *cstr = "非静态的我说中文?";
//String类的jclass
jclass str_cls = (*env)->FindClass(env, "java/lang/String");
jmethodID constructor_mid = (*env)->GetMethodID(env, str_cls, "<init>", "([BLjava/lang/String;)V");
//char * -> char[] ->jbyteArray -> jbyte *
jbyteArray bytes = (*env)->NewByteArray(env, strlen(cstr));
//bytes数组赋值
(*env)->SetByteArrayRegion(env, bytes, 0, strlen(cstr), cstr);
//charsetName="utf-8"
jstring charsetName = (*env)->NewStringUTF(env, "UTF-8");
//返回utf-8中文编码jstring
return (*env)->NewObject(env, str_cls, constructor_mid, bytes, charsetName);
}
//静态的
JNIEXPORT jstring JNICALL Java_com_fly_TestJni_getCStringStatic
(JNIEnv *env, jclass jcs){
char *cstr = "静态的我说中文?";
//String类的jclass
jclass str_cls = (*env)->FindClass(env, "java/lang/String");
jmethodID constructor_mid = (*env)->GetMethodID(env, str_cls, "<init>", "([BLjava/lang/String;)V");
//char * -> char[] ->jbyteArray -> jbyte *
jbyteArray bytes = (*env)->NewByteArray(env, strlen(cstr));
//bytes数组赋值
(*env)->SetByteArrayRegion(env, bytes, 0, strlen(cstr), cstr);
//charsetName="UTF-8"
jstring charsetName = (*env)->NewStringUTF(env, "UTF-8");
//返回utf-8中文编码jstring
return (*env)->NewObject(env, str_cls, constructor_mid, bytes, charsetName);
}
ps:说明: 上面new 了一个String 返回 为UTF-8格式,注意这里如果你的c文件保存文件类型是GB2312那么对应//charsetName=”GB2312” jstring charsetName = (*env)->NewStringUTF(env, “GB2312”); 这里这么繁琐是为了处理c返回string出现乱码
5.生成->生成解决方案,然后把x64->debug->找到生成的dll文件,然后把dll文件复制到java项目里面的根目录中去,然后在java中加载动态库,在main函数中调用dll里面的方法:
package com.fly;
public class TestJni {
//非静态的
public native String getCString();
//静态的
public native static String getCStringStatic();
public static void main(String[] args) {
TestJni tj = new TestJni();
System.out.println(tj.getCString());
System.out.println(TestJni.getCStringStatic());
}
//加载动态库
static {
System.loadLibrary("JNI");
}
}
运行:
---代码下载--------
本项目源码下载:《JNI开发之javah生成静态和非静态的两个头文件区别源码下载》注意:此源码C项目中已经生成了dll动态库,可直接使用!
--------完----------