Baple的专栏

博观约取

linux下java jni调用.so文件的方法

刚刚试过一个这样的例子,省事起见,略改并记录如下:

//package net.wangliping;
  2 public class Hello
  3 {
  4     static
  5     {
  6
  7         System.loadLibrary("goodluck");
  8     }
  9
 10     public native static int get();
 11     public native static void set(int i,String s);
 12
 13     public static void main(String[] args)
 14     {
 15         try{
 16         Hello test = new Hello();
 17         test.set(10,"5555");
 18         System.out.println(test.get());
 19         }catch(Exception ex)
 20         {
 21           System.out.println("ssssss");
 22         }
 23     }
 24 }

OK java类有了。

下面javac Hello.java

然后再javah Hello

生成了Hello.h

然后编写Hello.c

  1 #include "Hello.h"
  2
  3 int i = 0;
  4
  5 JNIEXPORT jint JNICALL Java_Hello_get(JNIEnv *env, jclass jc)
  6 {
  7     return i;
  8 }
  9
 10 JNIEXPORT void JNICALL Java_Hello_set(JNIEnv *env, jclass jc, jint j,jstring s)
 11 {

 13         char * tsetstr=(char*)(*env)->GetStringUTFChars(env, s, NULL);//注意此处jstring和char *的转换
 14         printf("%s--------\n",tsetstr); 

15     i = j;
 16 }

保存,然后执行如下编译指令:

  1 gcc -fPIC -D_REENTRANT -I/usr/java/jdk1.6.0_31/include -I/usr/java/jdk1.6.0_31/include/linux -c Hello.c
  2 gcc -shared Hello.o -o libgoodluck.so

此时就生成了libgoodluck.so

注意为了让java找到此so,运行:export LD_LIBRARY_PATH=.,将当前目录(so文件目录,不包括文件名)加入此环境变量。

然后运行java Hello,好屏幕上打出了10.

然后测试下传入String型的参数,对应的jni定义应为jstring,但却出了些问题,在显示结果时仿佛内存溢出的样子。

后来查了查,需对jstring和char *作一个转换,如代码中所示,然后结果就正常。


补充:

6.将第5步中编写的HelloJNI.c文件,编译成.o文件

gcc -fPIC -D_REENTRANT -I/usr/lib/jvm/java-1.5.0-sun-1.5.0.19/include -I/usr/lib/jvm/java-1.5.0-sun-1.5.0.19/include/linux -c HelloJNI.c

注:/usr/lib/jvm/java-1.5.0-sun-1.5.0.19/include 是jni.h头文件所在的路径
/usr/lib/jvm/java-1.5.0-sun-1.5.0.19/include/linux 是jni_md.h所在的路径

7.将第6步中生成的HelloJNI.o文件编译成.so库文件

gcc -shared HelloJNI.o -o libgoodluck.so

注:和windows下不同,linux的库文件必须是以libxxx.so形式命令的(或者 libxxx.so.y,y是版本号),lib前缀是为了系统能够识别它,xxx是java代码System.loadLibrary("xxx");中引用库的名字。

将第7步中生成的libgoodluck.so文件拷贝到java的加载库LD_LIBRARY_PATH指向的路径中。
前提是你有足够的权限,如果没有sudo权限的同学,用下面的方法:
1) 在/home下建立一个用来存放.so库文件的目录,比如/home/swan/lib
2) 把libgoodluck.so文件拷贝到该目录下
3)打开Terminal,运行如下命令

export LD_LIBRARY_PATH=/home/swan/lib

只在当前shell下有效...

另外,以下方法可以直接利用绝对路径来load这个so库文件,从而无需做上述的放置path或者更改库路径的动作。

static {
    System.load("/home/swan/test/libgoodluck.so");
}

阅读更多
文章标签: java jni so linux
个人分类: Linux JAVA C/C++
想对作者说点什么? 我来说一句

没有更多推荐了,返回首页

加入CSDN,享受更精准的内容推荐,与500万程序员共同成长!
关闭
关闭