关闭

编写JNI的一点心得

标签: jniDLLMyEclipse
184人阅读 评论(0) 收藏 举报
分类:

    在公司一直负责向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++动态库。

0
0

查看评论
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
    个人资料
    • 访问:9786次
    • 积分:197
    • 等级:
    • 排名:千里之外
    • 原创:36篇
    • 转载:3篇
    • 译文:0篇
    • 评论:0条