zoukankan      html  css  js  c++  java
  • [转]Linux下使用JNI的常见问题及解决方案

    Linux下使用JNI的常见问题及解决方案

     转载地址:http://www.cnblogs.com/javawebsoa/p/3220069.html
     
    我碰到的问题是bad value
    参考这里解决的
     

    linux生成动态库时遇到了relocation R_X86_64_32 against `.rodata' can not be used when making a shared object; recompile with -fPIC错误。

    由于我的系统是AMD64位的,所以需要在编译的时候添加 -fPIC选项

    解决方法:

    例如:

    g++ -c -fPIC head.cpp    生成head.o

    g++ -fpic -shared -o libfun.so head.o 

     
     

    JNI是java和C/C++混合编程的接口,可以很方便地实现java调用C/C++语言。具体的使用方法,网上有很多教程,在此不做过多介绍。本博客只关注在使用JNI的过程中的常见问题。

    1.     生成头文件用命令:javah*.class

         这是错误的。运行上述命令会提示:java.lang.IllegalArgumentException: Not a valid class name:SegNative.class错误。错误原因和利用java命令运行程序一样,只需要指出前缀即可,无需给出.class后缀。

    2.     版本问题

        jdk6和jdk7中某些JNI方法稍有不同,注意转换。例如,C中获取字符串的方法GetStringUTFChars在两个jdk版本中就不同。老的jdk6版本使用方法为:

    char* name=(char*)(*env)->GetStringUTFChars(env,Name,NULL);

    而在jdk7中,方法调用变为:

    const char* name=env->GetStringUTFChars(Name,0);

    其他的版本问题及函数参数含义可以通过查看API获得更全面的资料。

    3.     利用g++编译源文件找不到jni.h头文件

    可以在编译时利用-I选项指定jni.h头文件所在目录:

    g++ -I/usr/local/jdk1.7.0_25/include/ ……

    4.     利用g++编译源文件找不到jni_md.h

    这是因为在jni.h中引用了jni_md.h头文件,该头文件和jni.h不在一个目录下,所以我们还需要再指定jni_md.h的目录:

    g++ -I/usr/local/jdk1.7.0_25/include/  -I/usr/local/jdk1.7.0_25/include/linux/……

    可以看出jni_md.h放在和jni.h同级的目录linux下。

    5.     不会生成动态链接库

    生成动态链接库,需要在编译时声明-shared选项:

    g++ -I /usr/local/jdk1.7.0_25/include/  -I /usr/local/jdk1.7.0_25/include/linux/SegNative.cpp –shared –o lib***.so

    此外,我们也无需先生成相应的.o文件,直接指定动态链接库的名字即可。

    6.     编译动态链接库报错:couldnot read symbols: Bad value

    需要在编译的时候指定选项:-fPIC。

    g++ -I /usr/local/jdk1.7.0_25/include/  -I /usr/local/jdk1.7.0_25/include/linux/SegNative.cpp –shared –o lib***.so -fPIC

    7.     运行的时候找不到动态链接库

    这个问题主要有两个原因:

    • 生成的动态链接库名字不对:我们在java语言中声明的动态链接库如果名为A,则我们在编译时则需要将动态链接库的名字声明为libA.so,否则会报错。
    • 路径不对,java找不到动态链接库。java会在特定的目录寻找动态链接库,可以通过打印java.library.path查看java会在哪些目录查找动态链接库:
    System.out.println(System.getProperty("java.library.path"));

    我的电脑打印结果为:

    .:/opt/intel/impi/3.2.1.009/lib/:/usr/local/cuda/lib/:/root/NVIDIA_CUDA_SDK/lib/:/root/NVIDIA_CUDA_SDK/common/lib/:/usr/java/packages/lib/amd64:/usr/lib64:/lib64:/lib:/usr/lib

    我们可以看到相关lib都包括在该路径下。特别注意一点是第一个路径是.,这表示java会在当前路径下寻找相关动态链接库。因而只要我们将动态链接库和.class文件放在一起就不会存在找不到动态链接库的问题。如果打印中不包括当前目录,我们可以通过修改LD_LIBRARY_PATH指定当前目录。

            此外,我们也可以在运行的过程中指定:

    java –Djava.library.path=”/home/savedlib/”executablefile

    利用这种方法,程序可以指定不在当前目录的动态链接库。

  • 相关阅读:
    DevExpress WinForms v21.1 重磅升级桑基图控件
    UI组件库Kendo UI for Angular R3 2021新版亮点 支持Bootstrap 5
    Java随笔
    oracle 排序性能 监控,Oracle 常用性能监控SQL语句
    Oracle数据库管理常用的监控脚本极大的简化运维工作
    oracle误删除数据的恢复方法
    Oracle数据库之同义词
    MVCC详解
    goldengate classic extract在什么情况需要重建以及如何重建
    Oracle OGG Kafka
  • 原文地址:https://www.cnblogs.com/Crysaty/p/6704991.html
Copyright © 2011-2022 走看看