简介:Java调用动态链接库(dll,so)有两种方式:JNI和JNA
JNI: 步骤繁琐,基本套路就是编写java类,定义native方法,编译成class文件,用javah命令编译出头文件(.h)编写JNI实现,编译城动态链接库文件..........
JNA:(JNI的深度封装)从maven中引入java包,编写jna实现代码,使用现成的动态链接库文件运行程序即可;
maven坐标:
<dependency>
<groupId>net.java.dev.jna</groupId>
<artifactId>jna</artifactId>
</dependency>
版本号用最新的就行;
伪代码: java
public class JnaTest {
private static final Logger logger = LoggerFactory.getLogger(JnaTest.class);
private final NetLibrary netLibrary;
private final Gpslibrary gpslibrary;
private static final GpsCallbackImpl callBack = new GpsCallbackImpl();
public JnaTest() {
System.setProperty("jna.encoding", "GBK");
netLibrary = NetLibrary.INSTANCE;
gpslibrary = Gpslibrary.INSTANCE;
}
public interface NetLibrary extends Library {
NetLibrary INSTANCE = (NetLibrary) Native.loadLibrary(FileUtil.getTmpDirPath() + "/libnetclient.so", NetLibrary.class);
}
public interface Gpslibrary extends Library {
Gpslibrary INSTANCE = (Gpslibrary) Native.loadLibrary(FileUtil.getTmpDirPath() + "/libgetgps.so", Gpslibrary.class);
int GPS_Initial();
int GPS_SetMsgCallBack(GpsCallback pFn, Object pContext);
}
public static void Main(String[] args) {
int i = Gpslibrary.INSTANCE.GPS_Initial();
logger.info("GPS_Initial 返回值:" + i);
int j = Gpslibrary.INSTANCE.GPS_SetMsgCallBack(callBack, null);
}
}
public class GpsCallbackImpl implements GpsCallback {
private static final Logger logger = LoggerFactory.getLogger(RealtimebusDataProcessorApplication.class);
@Override
public void invoke(String pGps, int iLen, String pDeviceId, String pDevName, int iDeviceId, int iParam1, int iType, int pContext) {
logger.info(String.format("pGps =%s,iLen =%s,pDeviceId =%s,pDevName =%s,iDeviceId =%s,iParam1 =%s,iType =%s",
pGps, iLen, pDeviceId, pDevName, iDeviceId, iParam1, iType));
}
}
public interface GpsCallback extends Callback {
void invoke(String pGps, int iLen, String pDeviceId, String pDevName, int iDeviceId, int iParam1, int iType, int pContext);
}
c++:
#ifndef GPSDLL_H_
#define GPSDLL_H_
extern "C" {
int GPS_Initial();
int GPS_SetMsgCallBack(void *pFn, void *pContext);
int GPS_LoginServer_Ex(char *pLoginName, char *pLoginPwd,char *pServerIp, int iServerPort);
}
#endif /* GPSDLL_H_ */
注意事项:
char 指针对应的就是java的String;
GPS_SetMsgCallBack方法的入参是个函数指针,这个对应的就是GpsCallback 的实例;但是GpsCallback的实现类GpsCallbackImpl必须声明为static静态类型才能回调成功,这个地方调试了很久;
一般在使用JNA调用动态库的时候,DLL,so,h文件都会由C++编写方提供,当然,我们写JNA程序的时候,重要的就是拿到.h文件,了解里面的方法定义,编写出对应的Java实现