java jni 调用.so动态库

最近要用到JNI调用动态库,原来根本没接触过有没有,完全听不懂别人说的啥啊,自己鄙视自己一把。


从别的部门同事那里拿来的源码都不会用,于是就学习了一下如何从c文件生成.so文件,再供java调用。


有相当部分内容是网上找来的,自己汇总了一下。


第一步,从.c生成到.so

http://zhidao.baidu.com/link?url=hTspQ62DHH0Cu-n0pQkMSUL7R6JMNLLauTHM-iHJ8B-Bsdnj4zohUAOZKI4R2Vwmh-DIk6IVkN95rPW7KcOQB_(这个简单明了)

http://bbs.chinaunix.net/thread-136374-1-1.html(这个更详细一点)

gcc -c -fPIC daniels.c 			 		--生成 daniels.o
 
  
gcc -shared -fPIC -o daniels.so daniels.o	--生成 daniels.so动态库
完了,上述产生的.so文件不能被java正常调用。
我找到了最正确的大神的博客。就这么地吧。
http://blog.chinaunix.net/uid-20180960-id-1972669.html
 
  
复制粘贴一下,防止回头找不到。
 
  
Linux平台Java调用so库-JNI使用例子
2010-08-11 22:17

1.确保gcc编译器已安装

2.编写HelloJNI.java代码,用native声明需要用C实现的函数。
如果源程序是包含在package里的话,应该建立同样的文件夹结构,比如/home/swan/test/net/wangliping/HelloJNI.java

 
     

package net.wangliping

public class HelloJNI
{
    static
    {

        System.loadLibrary("goodluck");
    }

    public native static int get();
    public native static void set(int i);

    public static void main(String[] args)
    {
        HelloJNI test = new HelloJNI();
        test.set(10);
        System.out.println(test.get());
    }
}

3.在HelloJNI.java文件所在目录下编译.java文件。

javac HelloJNI.java

4.在~/Desktop下编译第三步中生成的.class文件,生成对应的.h头文件,本例中生成的头文件名为 net_wangliping_HelloJNI.h

javah net.wangliping.HelloJNI

5.编写HelloJNI.c文件,实现引用第4步中生成的.h头文件,并实现其中声明的方法。

 
     

#include "net_wangliping_HelloJNI.h"

int i = 0;

JNIEXPORT jint JNICALL Java_net_wangliping_HelloJNI_get(JNIEnv *env, jclass jc)
{
    return i;
}

JNIEXPORT void JNICALL Java_net_wangliping_HelloJNI_set(JNIEnv *env, jclass jc, jint j)
{
    i = j;
}

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");中引用库的名字。

8.将第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");
}

9.在运行HelloJNI.class

java net.wangliping.HelloJNI

一切正常后,可以看到运行結果是输出了10,其值是由C语言代码实现并返回的。


转载的。出处:http://blog.chinaunix.net/uid-20180960-id-1972669.html

你可能感兴趣的:(工作日志)