jni实例

     主要参考了  https://www6.software.ibm.com/developerworks/education/j-jni/section2.html。但它的例子适用于Solaris,在linux各种发行版上可能会有问题。这里只介绍一下从java代码中访问本地库的例子

   第一步,生成java代码,主要是声明那些native的函数,以便用javah自动生成头文件。
=============================Ictclas.java=====================================
public class Ictclas
{
    public native boolean ICTCLAS_Segment_Init(String sInitDirPath, String sUserDynamicPath );
  public native boolean ICTCLAS_Segment_Exit();
}
用native声明的函数都在共享库中(.so)。
运行 javac Ictclas.java 生成Ictclas.class
然后 javah Ictclas
此时会生成一个 Ictclas.h的文件,改文件你无需更改,只要在.cpp中包含即可。
======================== Ictclas.h===========================
/* DO NOT EDIT THIS FILE - it is machine generated */
#include <jni.h>
/* Header for class Ictclas */

#ifndef _Included_Ictclas
#define _Included_Ictclas
#ifdef __cplusplus
extern "C" {
#endif
/*
 * Class:     Ictclas
 * Method:    ICTCLAS_Segment_Init_Java
 * Signature: (Ljava/lang/String;Ljava/lang/String;)Z
 */
JNIEXPORT jboolean JNICALL Java_Ictclas_ICTCLAS_1Segment_1Init_1Java
  (JNIEnv *, jobject, jstring, jstring);

/*
 * Class:     Ictclas
 * Method:    ICTCLAS_Segment_Exit_Java
 * Signature: ()Z
 */
JNIEXPORT jboolean JNICALL Java_Ictclas_ICTCLAS_1Segment_1Exit_1Java
  (JNIEnv *, jobject);

#ifdef __cplusplus
}
#endif
#endif

第二步  有了.h文件后,剩余的函数实现就跟c/c++常用方法一样了。用 g++ -shared -fPIC -o libjni.so *.cpp 把源代码生成.so库。(默认都是以lib***.so,当System.loadLibrary("***"),系统默认会加上lib 和so)

第三部 在java中应用该共享库,System.loadLibrary("jni");把libjni.so载入你的java程序中。在linux下,所有的库文件都有lib开始 .so结尾,即使是java也遵循了这个命名规则,所以你在loadLibrary 时只要传入 "jni"即可。当然你还需要注意你的libjni.so是否在ld的搜索目录中,如果不在就会出现这个错误。搜索目录 用 LD_LIBRARY_PATH设置即可。

 


JNI: UnsatisfiedLinkError 错误汇总  no library , no native function。一般情况下,如果本地库或者本地函数无法找到就会有UnsatisfiedLinkError的exception产生。

 Exception in thread "main" java.lang.UnsatisfiedLinkError: no Sample1 in java.library.path
        at java.lang.ClassLoader.loadLibrary(ClassLoader.java:1709)
        at java.lang.Runtime.loadLibrary0(Runtime.java:823)
        at java.lang.System.loadLibrary(System.java:1030)
        at Sample1.main(Sample1.java:10)


很多jni的例子是没有package句子的,如果加了package  com.MyPackage;那么在生成头文件的时候,你必须加上class的路径。

javah  com.MyPackage.MyClass

 

linux/unix下:

 System.loadLibrary("name"), "name"并不是库的真正名字,库的真正文件名为libname.so,如果是 System.loadLibrary("libname.so")那就会得到UnsatisfiedLinkError了。linux加载.so库文件时是按照 ld.so.conf和LD_LIBRARY_PATH设定的目录来搜索,如果你的libname.so不再这些路径中, 那么也会得到一个UnsatisfiedLinkError。说白了都是找不到so库文件。如果你是在debug,java -debug,那么必须在库文件名后面加上_g,即System.loadLibrary("name"), 在debug模式下是链接 libname_g.so的。

 

windows

  类似于linux,System.loadLibrary("name")链接 name.dll. 在debug模式下链接  name_g.dll. System.loadLibrary的参数只能是库文件名,不能有path,它是以java.library.path为默认搜索路径的,可以在启动时指定。System.load可以从任意指定路径加载lib。为了屏蔽linux和windows的区别,可以用System.load(home_path+System.mapLibraryName("ictclas"));mapLibraryName会根据不同的os平台来生成真正的lib名称。



第四步
java sample就能得到你想要的结果。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 6
    评论
评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值