最近学习cocos2dx,的lua绑定机制,用到了Jni,可是现在目前的3.0版本的Demo工程文件太大,看起来不太方便,于是决定自己先尝试学习一下jni的实现远离,从最简单的java显示helloworld程序开始。
首先用eclipse创建java应用,加入包com.testJni和testJni.java文件
package com.testJni; public class testJni{ static{ System.loadLibrary("testJni"); } private native void display(); public static void main (String[] args){ new testJni().display(); } }
这里display方法的native关键字表示了这是一个使用jni实现的函数,来自于testJni这个外部库,编译一下在bin目录下生成了class文件,然后我们要利用javah生成c语言的头文件,这一步也是卡了我很久的一步,首先我们来看一看javah这个命令
它有两个关键参数 -jni和-classpath,classpath指定了加载类的路径,但是不管我怎么设置,一直会提示我找不到类,后来我百度了很多文章,发现javah这条命令执行位置必须是源码目录,即src目录下,我将class文件拷贝到目录下还是不行,多次尝试之后我发现-jni的路径必须是包名+类名的路径(java文件的路径),即javah执行路径是src目录,-classpath指定class的路径,-jni执行java文件路径,对应我的工程文件命令是
javah -classpath D:workspace estJniin -jni com.testJni.testJni
这样就顺利生成了.h文件
/* DO NOT EDIT THIS FILE - it is machine generated */ #include <jni.h> /* Header for class com_testJni_testJni */ #ifndef _Included_com_testJni_testJni #define _Included_com_testJni_testJni #ifdef __cplusplus extern "C" { #endif /* * Class: com_testJni_testJni * Method: display * Signature: ()V */ JNIEXPORT void JNICALL Java_com_testJni_testJni_display (JNIEnv *, jobject); #ifdef __cplusplus } #endif #endif
之后我们编写c文件实现Java_com_testJni_testJni_display这个方法
#include <jni.h> #include <stdio.h> #include "testJni.h" JNIEXPORT void JNICALL Java_com_testJni_testJni_display(JNIEnv *env, jobject obj) { printf("testJni load dll is here! "); printf("hello world! "); return; }
利用vs编译生成dll链接库,需要注意的是需要导入jni相关的jni.h(JAVA_HOME/include),和jni_md.h(JAVA_HOME/include/win32),这JAVA_HOME指的是你的jdk路径,还有因为我的电脑安装的是64位操作系统,在project编译属性中要选择machine64而不是machine86,将生成的dll文件放在java工程目录下,设置java build path 的Native library location为dll所在路径,然后运行