接触jni的这3天

来源:互联网 发布:淘宝信用管理在哪里 编辑:程序博客网 时间:2024/05/22 03:43

要养成总结的好习惯。。之前没写几次就没继续了。。重新开始。


目的是android开发中要调用C库——vrlib.so,这个库肯定不能直接拿来用的。。所以boss要我自己写个库包一下。


遇到的第一个问题是我操作系统学的不好,不知道如何一个库去访问另一个库里的东西。

答案是只要经过链接就可以了。


遇到的第二个问题是我想windows下的动态库是dll,那我怎么去生成.so的动态库呢,那就去linux下弄吧。

复习了一下linux下动态库的生成。指令如下:

gcc -shared -fpic -o libtest.so test.c

使用动态库的指令如下:

gcc -o main myuse.c  -ltest

这里要注意生成的main可能提示错误说找不到libtest.so库,因为需要把这个库放在系统路径下或者把你的路径加入程序搜索路径中

(参照http://blog.csdn.net/macky0668/article/details/3221756)

然后设置虚拟机linux的ip,用了 SSH Secure File Transfer Client工具把.so工具转到windows下。


第三个问题是发现linux下搞来的.so用cygwin编译的过程中死活编译不过,被老板鄙视了 “linux下的库android怎么能用呢?” 

天真的我以为后缀一样那就一样了。。

然后就用cygwin重编译了一个库。


第四个问题是现在库有了, 怎么链接库呢。

学了一下android.mk的写法,别的没学,链接动态库如下,别的应该差不多吧。

LOCAL_PATH := $(call my-dir) 路径什么的到当前路径什么的include $(CLEAR_VARS)  清空变量的意思,固定格式LOCAL_MODULE := my-init    随便一个名字,模块名字LOCAL_SRC_FILES := libtest.so      要用的动态库include $(PREBUILT_SHARED_LIBRARY)   include $(CLEAR_VARS)LOCAL_MODULE    := mylib     生成的库名字LOCAL_SHARED_LIBRARIES := my-init   加载前边那个模块LOCAL_SRC_FILES := my.cppinclude $(BUILD_SHARED_LIBRARY)


第五个问题是生成动态库去用的时候用.cpp竟然失败了。。

然后后来知道原因,具体如下:

http://www.cnblogs.com/HappyXie/archive/2011/01/07/1929369.html

解决办法很简单就是文件开始加上

#ifdef __cplusplusextern "C" {#endif
结尾加上

#ifdef __cplusplus}#endif


第六个问题是竟然忘了怎么加载库。。

static{     System.loadLibrary("test");}



第七个问题是c怎么访问java,也就是jni的知识了,查了一下好多东西头疼,就没继续弄想着第二天继续吧。

其实总结如下:(我只用到了访问变量,访问方法没有去学,所以下边提到的都是指变量)

由class根据名字和签名获取id 继而根据id去访问变量。

比如要访问一个二维数组。

jclass cls = env->FindClass("com/ice/test");jfieldID fid_arrays = env->GetFieldID(cls,"data","[[J");jobjectArray arrays = (jobjectArray)env->GetObjectField(obj, fid_arrays);jarray myarray = (jarray)env->GetObjectArrayElement( arrays, i);   //i行  jlong *coldata = env->GetLongArrayElements((jlongArray)myarray, 0);    //0是指一个模式,具体的参照手册吧for (int j(0);j<128;j++)num = coldata[j];






第八个问题一开始以为jni就那么简单了,使用过程中果然错了。

总结起来就两点:

1.jlong *coldata = env->GetLongArrayElements((jlongArray)myarray, 0);   

之后要释放

env->ReleaseLongArrayElements((jlongArray)myarray,coldata,0);

不释放的话第二次再用这个函数就会出错。

2.jarray myarray = (jarray)env->GetObjectArrayElement( arrays, i);  

之后要释放

env->DeleteLocalRef(myarray);

这个的解释如下:
从java虚拟机创建的对象传到本地c/c++代码时会产生引用。根据java的垃圾回收机制,只要引用存在就不会触发该引用指向的java对象的垃圾回收。

(摘自http://www.cnblogs.com/codc-5117/archive/2012/09/06/2672833.html)

这个问题耽误了很多时间,做了很多实验去研究,最后是在文档里找到答案的,说明看文档看手册的重要性。、



暂时先这样,项目进行到现在基本只剩下一点问题了,刚在纸上写了计划,希望可以一周内都搞定吧(希望不要再出难搞定的bug了。。)。

和女朋友吵架了,还有一些事情困扰着,觉得累先不去想了,认真努力工作,做完项目请假回家呆几天。

0 0
原创粉丝点击