前言
本文主要描述了利用jni傳遞和返回基本數(shù)據(jù)類型(int),采用了java和c語言,操作系統(tǒng)為ubuntu linux,無ide
1 java程序
采用最基本的java程序,無任何復雜操作
/**
* Created by act64 on 2017/5/25.
*/
public class JniHello {
static{
//在linux系統(tǒng)下,含android ,此命令自動解析為
//加載 lib目錄下的libnativehello.so文件
System.loadLibrary("nativehello");
}
public static void main(String[]arg){
JniHello jniHello =new JniHello();
System.out.println( jniHello.hello(1));
}
//native 表示這是個native方法
public native int hello(int num);
}
c 文件
之前寫過的博客簡單起見,用javac javah命令生成 頭文件,然后使用,這次采取jniOnload的方式自定義適配,更靈活也更明確
程序名hello.c
#include <stdio.h>
#include <jni.h>
//這是c程序的實現(xiàn)函數(shù),基本數(shù)據(jù)類型的使用比較簡單
jint c_hello(JNIEnv * env, jobject mJobject,jint val){
printf("hello,%d,jni",val);
return 100;
}
//這是jni.h提供的方法映射結構體,用于映射
//java方法和c方法
//三個參數(shù)為 java函數(shù)名 , 描述符,和c的函數(shù)指針
const JNINativeMethod methods[]={
{"hello","(I)I",(jint *)c_hello},
};
//此JNI_OnLoad是系統(tǒng)函數(shù)
//當java loadlibrary時會自動調(diào)用
//
JNIEXPORT jint JNICALL
JNI_OnLoad(JavaVM *jvm, void *reserved)
{
JNIEnv *env;
jclass cls;
//獲得context,并且取得目標java類
if ((*jvm)->GetEnv(jvm, (void **)&env, JNI_VERSION_1_4)) {
return JNI_ERR; /* JNI version not supported */
}
cls = (*env)->FindClass(env, "JniHello");
if (cls == NULL) {
return JNI_ERR;
}
//將java方法和對應的c方法映射,第四個參數(shù)是映射的條數(shù)
if((*env)->RegisterNatives(env,cls,methods,1)<0){
return JNI_ERR;
}
return JNI_VERSION_1_4;
}
編譯
- 1 需要確保java文件和c文件在一個目錄下
- 2 cd 所在目錄 編譯so文件
gcc -fPIC -I /usr/lib/jvm/java-1.7.0-openjdk-amd64/include -shared -o libnativehello.so hello.c
這里面 -I 后面的/usr/lib/jvm/java-1.7.0-openjdk-amd64/include目錄指的是jni.h所在的目錄,使用時請自行查找替換
- 3 編譯java文件
javac JniHello.java
- 4 測試代碼
//先 標示lib的目錄
//此操作在當前terminal一直有些
export LD_LIBRARY_PATH=./
java JniHello
輸出結果如下:
輸出.png
結語
折騰了一陣子,算是弄好了一個簡單地了,下一篇寫一寫jni和java類之間的交互