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

33 篇文章 0 订阅
12 篇文章 0 订阅

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

1

//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

2.

然后编写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");
}

  • 2
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
### 回答1: 这个过程涉及到JNIJava Native Interface)调用,它是一个Java虚拟机的桥接API,用于在Java和本地代码之间提供交互。JNI调用.so过程是指在Java程序中调用本地动态链接库(.so文件)的过程,它可以提高程序的性能,并且可以让Java程序访问本地系统的资源。 ### 回答2: JNI调用.so文件的过程如下: JNIJava Native Interface)是Java编程语言的一种编程框架,它允许Java代码调用C、C++或其他本地语言编写的代码。而.so(共享目标文件)是一种在Linux系统中广泛使用的动态链接库文件。通过JNI调用.so文件,可以在Java代码中调用本地代码完成一些特定的功能。 首先,在Java代码中使用关键字native标识一个方法,表明该方法是一个本地方法。然后,通过Java编译器编译Java文件,生成.class字节码文件。 接下来,在通过Java虚拟机(JVM)运行的过程中,当调用到native方法时,JVM会去查找包含该本地方法的动态链接库文件.so。 JVM通过JNI提供的函数,在库文件中找到对应的本地方法。这些函数包括:JavaVM结构体、JNI环境函数等。 在找到本地方法之后,JVM将Java的参数转换为本地方法可接受的参数类型,并将这些参数传递给本地方法。 本地方法执行完毕后,通过JNI将结果返回给Java。 总结来说,JNI调用.so文件的过程主要包括以下几个步骤:标识本地方法、编译Java文件生成.class文件、JVM加载.so文件、通过JNI将参数传递给本地方法、本地方法执行完毕后将结果返回给Java。 通过JNI调用.so文件,可以在Java代码中灵活地调用本地代码,实现一些底层功能,提高程序的效率和灵活性。 ### 回答3: JNIJava Native Interface)是一种允许Java程序与本地代码进行交互的技术。在JNI中,.so文件是指Linux系统下的共享库文件,也称为共享对象文件JNI调用.so文件的过程如下: 1. 编写Native方法:在Java代码中,先声明需要调用的本地方法,使用`native`关键字修饰,例如:`public native void nativeMethod();`。 2. 生成包含JNI方法的头文件:在命令行中使用`javac`命令编译Java代码生成.class文件,然后使用`javah`命令生成包含JNI方法的头文件。例如:`javah MyClass`,将生成一个名为`MyClass.h`的头文件。 3. 实现Native方法:根据生成的头文件,编写本地代码实现Native方法,可以使用C或C++来编写。将实现的代码保存为.c或.cpp文件,例如:`MyClass.c`或`MyClass.cpp`。 4. 编写JNI配置文件:创建一个名为`Android.mk`的文件,定义需要编译的源文件、依赖库、编译配置等信息。在该文件中,使用`include`命令引入NDK的配置文件。 5. 编译本地代码:在命令行中使用NDK提供的编译命令对本地代码进行编译,生成.so文件。例如:`ndk-build`。 6. 将.so文件Java代码关联:在Java代码中加载.so文件,使用`System.loadLibrary("库文件名")`方法。例如:`System.loadLibrary("mylibrary")`。该方法会在运行时将.so文件加载到JVM中。 7. 调用Native方法:在Java代码中,通过调用定义的Native方法来执行本地代码。例如:`nativeMethod();`。 8. 运行程序:在命令行或IDE中运行Java程序,即可进行JNI调用.so文件的过程。 总结:通过编写Native方法、生成头文件、实现本地代码、编写JNI配置文件、编译本地代码、关联.so文件调用Native方法这些步骤,就可以完成JNI调用.so文件的过程。JNI技术可以方便地在Java程序与本地代码之间进行交互,提供了一种扩展Java功能的方式。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值