锁定老帖子 主题:Java JNI 编程进阶
该帖已经被评为良好帖
|
|
---|---|
作者 | 正文 |
发表时间:2008-12-19
呃 不错 根据客户需要 有的地方是要用JNI实现的!
文章不错@@ |
|
返回顶楼 | |
发表时间:2008-12-19
最后修改:2008-12-19
引用 # JNIEXPORT jintArray JNICALL Java_org_danlley_jni_test_HelloJniTest_getDynamicArrayData
# (JNIEnv *env, jobject obj, jintArray args){ # jint buf[10]; # jint i; # env->GetIntArrayRegion(args, 0, 10, buf); # jint j=0; # for (i = 0; i < 10; i++) { # j=buf[i]; # j*=j; # buf[i]=j; # } # env->SetIntArrayRegion(args, 0, 10, buf); # return args; # } 请教一下。 这两个方法会进行array copy吧?因为intel的cpu都是小尾序的,而java一般是大尾序的。 对于int数组,也许jdk会做优化,在操作系统的内存里面实际上是小尾的,只不过对高层代码显示为大尾? 这个问题我觉得非常要紧,因为如果使用jni是为了提高性能的话,那么用途往往都是网络、磁盘IO、加密、压缩等操作,往往都要和数组打交道的,而且对性能要求很高。 例子里面是int数组,但更最重要的,我想应该是byte数组。byte数组就无所谓大尾小尾的问题了,能不能做到在一个地址空间工作呢,直接操作jbyteArray的地址里面的数据行不行,会有兼容问题吗? |
|
返回顶楼 | |
发表时间:2008-12-19
wangdi 写道 xieke 写道 如果用vc 编译动态库 实现 jni 就失去跨平台特性了,
我是用 mingw +cdt 或者 mingw+netbeans 编译 动态库, 这样可以做到一套c代码,windows linux下都能跑, 但是linux下动态库是so文件,windows下是 dll文件,所以算是半个跨平台把. 那你怎么编译的呢? 不是vc或者其他东东编译dll然后gcc编译so? 安装 mingw 后,即可在windows下用 gcc 直接编译 dll, 也就是说,只需要在 makefile 中把 .so后缀改为 .dll后缀就行了. |
|
返回顶楼 | |
发表时间:2008-12-19
AreYouOK? 写道 引用 # JNIEXPORT jintArray JNICALL Java_org_danlley_jni_test_HelloJniTest_getDynamicArrayData
# (JNIEnv *env, jobject obj, jintArray args){ # jint buf[10]; # jint i; # env->GetIntArrayRegion(args, 0, 10, buf); # jint j=0; # for (i = 0; i < 10; i++) { # j=buf[i]; # j*=j; # buf[i]=j; # } # env->SetIntArrayRegion(args, 0, 10, buf); # return args; # } 请教一下。 这两个方法会进行array copy吧?因为intel的cpu都是小尾序的,而java一般是大尾序的。 对于int数组,也许jdk会做优化,在操作系统的内存里面实际上是小尾的,只不过对高层代码显示为大尾? 这个问题我觉得非常要紧,因为如果使用jni是为了提高性能的话,那么用途往往都是网络、磁盘IO、加密、压缩等操作,往往都要和数组打交道的,而且对性能要求很高。 例子里面是int数组,但更最重要的,我想应该是byte数组。byte数组就无所谓大尾小尾的问题了,能不能做到在一个地址空间工作呢,直接操作jbyteArray的地址里面的数据行不行,会有兼容问题吗? 这两天也在考虑这个问题,暂时还没有办法,不知道有没有人可以直接在一个地址里操作 |
|
返回顶楼 | |
发表时间:2008-12-19
danlley 写道 AreYouOK? 写道 引用 # JNIEXPORT jintArray JNICALL Java_org_danlley_jni_test_HelloJniTest_getDynamicArrayData
# (JNIEnv *env, jobject obj, jintArray args){ # jint buf[10]; # jint i; # env->GetIntArrayRegion(args, 0, 10, buf); # jint j=0; # for (i = 0; i < 10; i++) { # j=buf[i]; # j*=j; # buf[i]=j; # } # env->SetIntArrayRegion(args, 0, 10, buf); # return args; # } 请教一下。 这两个方法会进行array copy吧?因为intel的cpu都是小尾序的,而java一般是大尾序的。 对于int数组,也许jdk会做优化,在操作系统的内存里面实际上是小尾的,只不过对高层代码显示为大尾? 这个问题我觉得非常要紧,因为如果使用jni是为了提高性能的话,那么用途往往都是网络、磁盘IO、加密、压缩等操作,往往都要和数组打交道的,而且对性能要求很高。 例子里面是int数组,但更最重要的,我想应该是byte数组。byte数组就无所谓大尾小尾的问题了,能不能做到在一个地址空间工作呢,直接操作jbyteArray的地址里面的数据行不行,会有兼容问题吗? 这两天也在考虑这个问题,暂时还没有办法,不知道有没有人可以直接在一个地址里操作 从理论上来说,我觉得至少byte数组是没有问题的,不过我不会写c/c++程序,没有试过。 不知道jdk的jni调用是怎么做的,比如System.arrayCopy方法,还有那些做压缩、加密的的本地代码。 |
|
返回顶楼 | |
发表时间:2008-12-20
AreYouOK? 写道 danlley 写道 AreYouOK? 写道 引用 # JNIEXPORT jintArray JNICALL Java_org_danlley_jni_test_HelloJniTest_getDynamicArrayData
# (JNIEnv *env, jobject obj, jintArray args){ # jint buf[10]; # jint i; # env->GetIntArrayRegion(args, 0, 10, buf); # jint j=0; # for (i = 0; i < 10; i++) { # j=buf[i]; # j*=j; # buf[i]=j; # } # env->SetIntArrayRegion(args, 0, 10, buf); # return args; # } 请教一下。 这两个方法会进行array copy吧?因为intel的cpu都是小尾序的,而java一般是大尾序的。 对于int数组,也许jdk会做优化,在操作系统的内存里面实际上是小尾的,只不过对高层代码显示为大尾? 这个问题我觉得非常要紧,因为如果使用jni是为了提高性能的话,那么用途往往都是网络、磁盘IO、加密、压缩等操作,往往都要和数组打交道的,而且对性能要求很高。 例子里面是int数组,但更最重要的,我想应该是byte数组。byte数组就无所谓大尾小尾的问题了,能不能做到在一个地址空间工作呢,直接操作jbyteArray的地址里面的数据行不行,会有兼容问题吗? 这两天也在考虑这个问题,暂时还没有办法,不知道有没有人可以直接在一个地址里操作 从理论上来说,我觉得至少byte数组是没有问题的,不过我不会写c/c++程序,没有试过。 不知道jdk的jni调用是怎么做的,比如System.arrayCopy方法,还有那些做压缩、加密的的本地代码。 恩,big-edian和little-edian确实是问题。 可以实际测试一下jint的尾序情况,看看高字节在那边。 我个人感觉jint应该做到了和在java上用int没区别,那从int->jint有没有什么我们不知道的东西。 |
|
返回顶楼 | |
发表时间:2008-12-20
jni的效率没有那么高。
jni对内存的开辟有限制。 |
|
返回顶楼 | |
发表时间:2008-12-20
最后修改:2008-12-20
引用 恩,big-edian和little-edian确实是问题。 可以实际测试一下jint的尾序情况,看看高字节在那边。 我个人感觉jint应该做到了和在java上用int没区别,那从int->jint有没有什么我们不知道的东西。 在操作系统的内存里面,数字是大尾还是小尾肯定是由CPU构架决定的。这样要读一个4字节int,只要把这4字节装进CPU的寄存器就行了,只要一个指令。8字节long在64位机上也只要一个指令。 否则,像下面的代码这样,效率岂不是太低了? java.io.DataInputStream public final int readInt() throws IOException { int ch1 = in.read(); int ch2 = in.read(); int ch3 = in.read(); int ch4 = in.read(); if ((ch1 | ch2 | ch3 | ch4) < 0) throw new EOFException(); return ((ch1 << 24) + (ch2 << 16) + (ch3 << 8) + (ch4 << 0)); } |
|
返回顶楼 | |
发表时间:2008-12-23
最后修改:2008-12-23
很不错!
要是能在里面再加上一些复杂点的对象,及JAVA对象方法的调用,就更全面了 |
|
返回顶楼 | |
发表时间:2008-12-23
JNI最大的缺点是多线程方面的应用支持不够。
内存泄露也是个很让人头疼的问题。 |
|
返回顶楼 | |