参考书籍《Java核心技术 卷II》。
本文仅提供jni的语法,不包含具体编译器的操作。
在Android Studio 2.3中使用jni的教程:http://mp.weixin.qq.com/s/5DHJa5E-lZzy21-9edxoIg
使用目的
虽然使用Java开发Android程序相对于用C有着各种各样的优势,但是Java也有一些不知的地方,比如能被轻松地反编译,所以在进行一些比较隐私的操作时,C是一个更好的选择。另外使用C也能提高不少程序的效率,进行一些底层的操作也比较方便。
简单使用
在Java类中放置一个使用native
关键字表示的本地方法,如下:1
2
3
4
5
6pulic class HelloJni {
/**
*类似于抽象方法不提供方法的具体实现
*/
public static native String hello();
}
为实现这个方法需建立一个与之对应的C语言函数。为了与之对应,必须使用完整Java方法名,例如:com.jay86.HelloJni,hello
,然后将.
替换为_
并加上Java_
前缀,例如:Java_com_jay86_HelloJni_hello
。完整代码如下:1
2
3
4
5
6
7
8
9
10
11
extern "C"
JNIEXPORT jstring JNICALL
Java_com_jay86_HelloJni_hello(
JNIEnv* env /*调用jni函数需要用到的东西,下面会看到*/,
jclass cl /*非静态时是jobject相当于this,静态时是jclass相当于Class*/) {
std::string hello = "Hello from C++";
return env->NewStringUTF(hello.c_str());
}
最后在HelloJni类中加载它:1
2
3
4
5
6
7
8
9
10
11pulic class HelloJni {
static {
/*native-lib是C\C++的文件名*/
System.loadLibrary("native-lib");
}
/**
*类似于抽象方法不提供方法的具体实现
*/
public static native String hello();
}
这样,一个jni程序就完成了。但是jni程序还有更多需要学习的。
参数传递与返回值
Java数据类型与C语言数据类型对应关系
Java | C | 字节 |
---|---|---|
boolean | jboolean | 1 |
byte | jbyte | 1 |
char | jchar | 2 |
short | jshort | 2 |
int | jint | 4 |
long | jlong | 8 |
float | jfloat | 4 |
double | jdouble | 8 |
实现简单参数传递
ps:方便起见,直接在之前的代码中添加了两个参数,并没有对其做任何操作。
Java中
1
2
3
4
5
6pulic class HelloJni {
static {
System.loadLibrary("native-lib");
}
public static native String hello(int a, double b);
}C中
1
2
3
4
5
6
7
8
9
10
11
extern "C" /*C++需要添加上这一句,不太清楚原因*/
JNIEXPORT jstring JNICALL
Java_com_jay86_HelloJni_hello(
JNIEnv* env,
jclass cl, jint a, jdouble b) {
std::string hello = "Hello from C++";
return env->NewStringUTF(hello.c_str());
}
字符串参数
由于C语言和Java语言的字符串存在一系列的不同,传递字符串时需要进行一些处理:
jstring -> char*
1
2
3
4jString jstr = "hello world";
char* cstr = (*env)->GetStringUTFChars(env, jstr, NULL);
//不再访问时释放
(*env)->ReleaseStringUtf(env, format, cformat);char* -> jstring
1
2
3
4
5
6
7
8
9//C
char cstr[] = "hello world";
jstring jstr;
jstr = (*env)->NewStringUTF(env, cstr);
//C++
std::string hello = "Hello from C++";
jstring jstr;
jstr = env->NewStringUTF(hello.c_str());