论坛首页 Java企业应用论坛

Java JNI 编程进阶

浏览 56890 次
该帖已经被评为良好帖
作者 正文
   发表时间:2008-12-19  
呃 不错 根据客户需要 有的地方是要用JNI实现的!
文章不错@@
0 请登录后投票
   发表时间: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的地址里面的数据行不行,会有兼容问题吗?


0 请登录后投票
   发表时间: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后缀就行了.
0 请登录后投票
   发表时间: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的地址里面的数据行不行,会有兼容问题吗?




这两天也在考虑这个问题,暂时还没有办法,不知道有没有人可以直接在一个地址里操作
0 请登录后投票
   发表时间: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方法,还有那些做压缩、加密的的本地代码。
0 请登录后投票
   发表时间: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有没有什么我们不知道的东西。
0 请登录后投票
   发表时间:2008-12-20  
jni的效率没有那么高。
jni对内存的开辟有限制。
0 请登录后投票
   发表时间: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));
    }
0 请登录后投票
   发表时间:2008-12-23   最后修改:2008-12-23
很不错!
要是能在里面再加上一些复杂点的对象,及JAVA对象方法的调用,就更全面了
0 请登录后投票
   发表时间:2008-12-23  
JNI最大的缺点是多线程方面的应用支持不够。

内存泄露也是个很让人头疼的问题。

0 请登录后投票
论坛首页 Java企业应用版

跳转论坛:
Global site tag (gtag.js) - Google Analytics