Java调用DLL或SO(C,C++)文件中的函数--极简版

原创
2021/10/29 10:16
阅读数 1K

简介: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实现

展开阅读全文
加载中
点击引领话题📣 发布并加入讨论🔥
0 评论
0 收藏
0
分享
返回顶部
顶部