最近由于手头有个项目,要用到以前的c的一些东西,涉及到了JNI,把步骤写一下吧,免得以后自己也忘记了。
网上的全是最简单的hello程序,实际中的项目复杂多了。。。
(1).首先是要求写带有native方法的类,个人理解其实JNI也就是个中间件,这一步不是很难。
在这里以Utils类为例吧,因为此类涉及到外部引入包android.jar,所以更复杂一点,案例较好.这里的loadLibrary("opengl-math")在windows下就是opengl-math.dll 了,所有的步骤做完后放到Java 的System.path 下就能被调用了。
(2). 接下来就是要把该类编译成class文件了。这里值得注意的是因为引入了外部包,所以编译的时候要加入-classpath<外部包路径> 参数
我的Utils.java是存放在common文件夹下的,所以用cd命令进入common文件夹后,输入命令:
javac -classpath D:/android/android-2.2_r01-windows/android.jar Utils.java
这样就可以了,生成了Utils.class 文件
(3).接下来生成头文件
进入到包的上面一层目录,我的目录是src/ro/brite/android/opengl/common/文件,所以cd到src,ro/brite/android/opengl/common这个就是包了,输入命令javah -classpath . -verbose ro.brite.android.opengl.common.Utils 进行编译,在src文件夹下生成了文件
我这里有三个文件,所以生成了三个
(4)生成dll文件
新建一个dll项目,个人经验空项目比较好,有时候预编译的东西莫名其妙就抛错了,头疼。
这里具体写的时候注意一点c和c++的语法差异,比如c会要求回调,类似jfloat* data = (*env)->GetDirectBufferAddress(env, buff);在c++中就不支持了。我最后是用c写的。
还有就是在c中变量的声明最好都放在函数最先开始的地方,这样子会减少报错的几率,算是小经验吧。
最后编译通过会在debug文件夹下生成dll文件,复制到所需要调用的class的同一文件夹下就能用了。或者放到系统路径,比如System32也可以。
ps:这里只是测试JNI实践文中涉及到android的代码只是为了方便才用到的,android项目的话最后是编译成so文件调用的,下次有机会再说。