使用Java调用DLL动态链接库的方案通常有几种方式:JNI, JNative,Jawin, Jacob.其中 JNative,Jawin, 调用方式很简单,google一下即刻解决,但是这两种方式都已不支持64系统, Jacob是Java-Com Bridge的缩写,也可以用来调用DLL。其底层也是使用JNI实现,也具有Windows 的平台依赖性,但是要求dll是可注册的,所以也有一定局限性;
回到最初的调用方式 :JNI(Java Native Interface)是Java语言本身提供的调用本地已编译的函数库的方法,本身具有跨平台性,可以在不同的机器上调用不同的本地库, JNI的应用方案是基于Java类和本地函数相映射的。其使用DLL的步骤还是相对比较麻烦,不但涉及到Java编程,还涉及到C/C++编程,一般来说,第三方提供的dll,我们需要用C++做一个中间件调用它(不建议C#实现),然后再由java去调用这给中间件以达到最终效果。
JNI的使用步骤是:
1、编写Java类,用该类将DLL对外提供的函数服务进行声明,其中的Java方法均声明为native,其方法 签名可以自定义,不实现函数体。
package com.my.util;
public class SMSUtil {
public static void main(String[] args) {
start(9, 9600);
sendMsg("测试", "189********");
stop();
}
static
{
System.loadLibrary("SMSService"); //vc++实现的中间件"SMSService.dll"
}
public static native int start(int port, int baudRate);
public static native int stop();
public static native int sendMsg(String msg, String phoneCode);
} 2、 编译成class, 在class根目录执行
Javah 生成 .h
命令: c:\workspace\smsutil\bin>javah com.my.util
生成 com_my_util_SMSUtil.h
生成的函数定义没有参数名称,所以需要对其做简单的修改:
JNIEXPORT jint JNICALL Java_com_my_util_SMSUtil_start
(JNIEnv * env, jclass obj, jint port, jint baudRate);
JNIEXPORT jint JNICALL Java_com_my_util_SMSUtil_stop
(JNIEnv * env, jclass obj);
JNIEXPORT jint JNICALL Java_com_my_util_SMSUtil_sendMsg
(JNIEnv * env, jclass obj, jstring jMsg, jstring jPhone);
3、编写C/C++代码实现.h头文件中声明的函数, 实现接口方法,可以在实现方法中调用第三方DLL库
打开vs2010,建立名称为SMSService的win32控制台应用程序。如下所示:

设置应用程序类型:DLL,附加选项:导出符号。如下图所示:

点击完成。
复制 %jdk%\include\win32\jni_md.h和%jdk%\include\jni.h 到项目根目录下,复制com_my_util_SMSUtil.h到项目根目录,com_my_util_SMSUtil.h文件的引用 include
删除SMSService.h ,SMSService.cpp 所有代码,然后在stdafx.h中写入:#include “com_my_util_SMSUtil.h", SMSService.cpp引用stdafx.h, 实现定义中的方法, 编译生成SMSService.dll,SMSService.lib, 复制到调用着的 system32目录,至此整个实现过程可以说已经完成。
4、接下来可以在 SMSService.cpp 中调用第三方dll
#include "stdafx.h"
#include "stdlib.h"
typedef DWORD (_stdcall *pSMSSendMessageFun)(char* Msg,char* PhoneNo);
typedef int (_stdcall *pSMSStartServiceFun)(int nPort,DWORD BaudRate , int Parity, int DataBits ,int StopBits,int FlowControl,char* csca);
typedef int (_stdcall *pSMSStopSericeFun)();
HINSTANCE hDll;
JNIEXPORT jint JNICALL Java_com_my_util_SMSUtil_start
(JNIEnv * env, jclass obj, jint port, jint baudRate)
{
hDll = LoadLibrary("SMSDLL.dll"); //调用程序目录下须要有此动态库文件
if(hDll == NULL)
{
return -1;
}
pSMSStartServiceFun SMSStartServiceFun;
SMSStartServiceFun = (pSMSStartServiceFun)GetProcAddress(hDll, "SMSStartService");
if(SMSStartServiceFun)
{
int iflag = SMSStartServiceFun(port,baudRate,2,8,0,0,"card");
if(iflag != 0)
{
printf("Service start success ");
return 0;
}
else
{
printf("Service start fail ");
pSMSGetLastErrorFun SMSGetLastErrorFun;
SMSGetLastErrorFun = (pSMSGetLastErrorFun)GetProcAddress(hDll, "SMSGetLastError");
char Err[1024];
memset(Err, 0, 1024);
if(SMSGetLastErrorFun)
{
int len = SMSGetLastErrorFun(Err);
if(len > 0)
{
printf(Err);
}
}
return -1;
}
}
else
{
return -1;
}
}
JNIEXPORT jint JNICALL Java_com_my_util_SMSUtil_stop
(JNIEnv *, jclass)
{
//HINSTANCE hDll = LoadLibrary("SMSDLL.dll")