您的位置:首页 > 其它

编写JNI的一点心得

2015-11-19 23:29 295 查看
    在公司一直负责向windows平台提供动态库,最多的就是给C#调用。然而Windows端项目差点夭折,同事写的算法,让医学影像损失严重。我不得不亲手编写,导致项目时间紧迫,越急越乱。

    然而在BS端,如今也需要调我的动态库,由于我一直没有写过JNI,于是给同事去整理,结果他花了两天时间,仍然没能调通。今天还是得自己动手。

    网上了解了一下,编写JNI的基本步骤。

    ①不用IDE,直接用编辑器编写类文件,cmd编译成class,生成头文件

    ②用MyEclipse新建项目,而且带有包名,仍然用cmd生成头文件

    第一种情况下,很顺利就通过了,只是不知道为什么动态库里的日志都没有打印,开始以为动态库没有加载成功,于是加了一些终端输出,来调试,确实是正常执行了。

    第二种情况,开始一直报java.lang.UnsatisfiedLinkError这个异常,在网上看到别人说什么,动态库必须用C来实现,文件后缀要是.c,让我那么大一个C++动态库用C再实现一遍,简直想自杀。不相信,继续找方法,有人还说是环境,或者是MyEclipse配置问题,可以在看到那个异常,明显是函数已经加载了,好像参数不匹配似的。

    详细情况是这样的:

    工程名:PatientService

    类名PatientServiceImpl 应同事要求,加    包名package com.annet.service;

public class PatientServiceImpl {

static

{

System.loadLibrary(“PatientServiceImpl”);

}

public native boolean init(String strSvrIP, int nPort);

public native String selectAllPatient(String strDeptNo);

public static void main(String args[])

{

}

    在cmd下生成头文件,com_annet_service_PatientServiceImpl.h

于是在vs2012新建DLL工程,PatientServiceImpl,自动生成PatientServiceImpl.cpp,添加jdk下的两个目录jdk/include和jdk/include/win32,由于这个动态库只是一个外壳,将C++动态在包装一下(避免重新将C++代码都改为JNI)要将工程设置为多字节。然后将刚刚生成的头文件添加过来,编译,成功。

    有没有注意到,头文件是com_annet_service_PatientServiceImpl.h,而cpp文件是PatientServiceImpl.cpp,一般在编写C++代码的时候,头文件和CPP文件都会成对出现,但是不成对出现的话,会不会有问题呢?理论上是没问题的,但是这里这样用却导致Java调用时出错了。

    最后的做法是,新建DLL工程com_annet_service_PatientServiceImpl,让CPP文件名和最后生成的动态库名字都是com_annet_service_PatientServiceImpl,而且在Java调用的时候,也是System.loadLibrary(“com_annet_service_PatientServiceImpl”); 这样才顺利让J2EE项目顺利启动,并成功调用C++动态库。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: