1. 苏葳的备忘录首页
  2. 编程

Linux下Java调用.so文件的方法

java so jniJava受其虚拟机语言的结构所限,提供跨平台能力的同时,却失去了一些跟底层联系紧密的功能。JNI就是Java对平台无关性缺点的一个有益补充。C语言编写的DLL或SO文件,如果能被Java语言调用的话,将能大扩展Java语言的适用范围。比如Tuxedo中间件通常提供了C接口,而Java接口Jolt是收费的。如果需要在Java服务中调用Tuxedo中间件,那么把C接口打包进SO文件由Java调用是个省钱的方案。

下面是一个简单的Java调用so的的例子,省事起见,略改并记录如下:

//package net.wangliping;
public class Hello
{
    static
    {
        System.loadLibrary("goodluck");
    }
    public native static int get();
    public native static void set(int i,String s);
    public static void main(String[] args)
    {
        try{
        Hello test = new Hello();
        test.set(10,"5555");
        System.out.println(test.get());
        }catch(Exception ex)
        {
          System.out.println("ssssss");
        }
    }
}

 

OK java类有了。

下面执行javac Hello.java

然后再执行javah Hello

生成了Hello.h

然后编写Hello.c

#include "Hello.h"
int i = 0;
JNIEXPORT jint JNICALL Java_Hello_get(JNIEnv *env, jclass jc)
{
    return i;
}
JNIEXPORT void JNICALL Java_Hello_set(JNIEnv *env, jclass jc, jint j,jstring s)
{
        char * tsetstr=(char*)(*env)->GetStringUTFChars(env, s, NULL);//注意此处jstring和char *的转换
        printf("%s--------\n",tsetstr);
   i = j;
}

 

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

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

此时就生成了libgoodluck.so

注意为了让java找到此so,运行:export LD_LIBRARY_PATH=.,将当前目录加入此环境变量。

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

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

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

原创文章,作者:苏葳,如需转载,请注明出处:https://www.swmemo.com/429.html

发表评论

邮箱地址不会被公开。 必填项已用*标注