通過JNA調用DLL超詳細代碼實戰

jopen 10年前發布 | 23K 次閱讀 JNA Java開發

0  JNA安裝

0.1 JNA是什么

JNA(JavaNativeAccess)框架是一個開源的Java框架,是SUN公司主導開發的,建立在
經典的JNI的基礎之上的一個框架。
JNA項目地址:https://jna.dev.java.net/
JNA使Java調用原生函數就像.NET上的P/Invoke一樣方便、快捷。
JNA的功能和P/Invoke類似,但編寫方法與P/Invoke截然不同。JNA沒有使用Annotation,
而是通過編寫一般的Java代碼來實現。
P/Invoke是.NET平臺的機制。而JNA是Java平臺上的一個開源類庫,和其他類庫沒有
什么區別。只需要在classpath下加入jna.jar包,就可以使用JNA。
JNA使Java平臺可以方便地調用原生函數,這大大擴展了Java平臺的整合能力。

0.2 加入

在eclipse 中將文章最后的JNA下載中的zip解壓放到一個記得住的文件夾然后在工程的JAVA Build Path中加入這兩個jar即可

通過JNA調用DLL超詳細代碼實戰

通過JNA調用DLL超詳細代碼實戰

1 使用步驟

1.1 編寫DLL

這里我們使用 code::blocks編寫dll

首先新建一個DLL工程

通過JNA調用DLL超詳細代碼實戰

建立完畢后我們可以看到這樣的結構

通過JNA調用DLL超詳細代碼實戰

其中有一個h文件和一個cpp文件

依葫蘆畫瓢 改寫這兩個文件就可以了,我們寫兩個函數,一個加一個階乘

main.h 改寫成

    #ifndef __MAIN_H__  
    #define __MAIN_H__  

    #include   

    /*  To use this exported function of dll, include this header 
     *  in your project. 
     */  

    #ifdef BUILD_DLL  
        #define DLL_EXPORT __declspec(dllexport)  
    #else  
        #define DLL_EXPORT __declspec(dllimport)  
    #endif  


    #ifdef __cplusplus  
    extern "C"  
    {  
    #endif  

    int add(int a,int b);  
    int factorial(int n);  

    #ifdef __cplusplus  
    }  
    #endif  

    #endif // __MAIN_H__  

main.cpp改寫成

    #include "main.h"  

    int add(int a,int b){  
        return a + b;  
    }  
    int factorial(int n){  
        int i;  
        int r = 1;  
        for(i=1;i
            r = r*i;  
        return r;  
    }  

    BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved)  
    {  
        switch (fdwReason)  
        {  
            case DLL_PROCESS_ATTACH:  
                // attach to process  
                // return FALSE to fail DLL load  
                break;  

            case DLL_PROCESS_DETACH:  
                // detach from process  
                break;  

            case DLL_THREAD_ATTACH:  
                // attach to thread  
                break;  

            case DLL_THREAD_DETACH:  
                // detach from thread  
                break;  
        }  
        return TRUE; // succesful  
    }  

其中DLLMain是動態鏈接庫的入口函數我們不用管它,點擊編譯按鈕

通過JNA調用DLL超詳細代碼實戰

這樣就生成了DLL文件了,我們在項目文件夾 bin文件夾下的Debug中可以找到編譯成了DLL文件,將這個文件拷貝到需要使用DLL的JAVA工程路徑下

通過JNA調用DLL超詳細代碼實戰

通過JNA調用DLL超詳細代碼實戰

這樣DLL文件就準備好了

1.2 編寫接口類

新建一個類,實現Library接口

    package implementation;  

    import com.sun.jna.Library;  
    import com.sun.jna.Native;  

    public interface JNATestDll extends Library {  
        JNATestDll instanceDll  = (JNATestDll)Native.loadLibrary("JNATestDLL",JNATestDll.class);  
        public int add(int a,int b);  
        public int factorial(int n);  
    }  

這樣就可以方便的調用這一DLL了

編寫一個GUI類用于展示結果

    package gui;  

    import implementation.JNATestDll;  

    public class GUI {  

        private JFrame frame;  
        private JTextField tfb;  
        private JTextField tfa;  
        private JTextField tfadd;  
        private JTextField tfn;  
        private JTextField tffactorial;  

        /** 
         * Launch the application. 
         */  
        public static void main(String[] args) {  
            EventQueue.invokeLater(new Runnable() {  
                public void run() {  
                    try {  
                        GUI window = new GUI();  
                        window.frame.setVisible(true);  
                    } catch (Exception e) {  
                        e.printStackTrace();  
                    }  
                }  
            });  
        }  

        /** 
         * Create the application. 
         */  
        public GUI() {  
            initialize();  
        }  

        /** 
         * Initialize the contents of the frame. 
         */  
        private void initialize() {  
            frame = new JFrame();  
            frame.setBounds(100, 100, 450, 300);  
            frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);  
            frame.getContentPane().setLayout(null);  

            JButton bntcompute = new JButton("compute");  
            bntcompute.addActionListener(new ActionListener() {  
                public void actionPerformed(ActionEvent e) {  
                    tfadd.setText(""+JNATestDll.instanceDll.add(Integer.valueOf(tfb.getText()), Integer.valueOf(tfa.getText())));  
                    tffactorial.setText(""+JNATestDll.instanceDll.factorial(Integer.valueOf(tfn.getText())));  
                }  
            });  
            bntcompute.setBounds(286, 180, 93, 23);  
            frame.getContentPane().add(bntcompute);  

            tfb = new JTextField();  
            tfb.setText("3");  
            tfb.setBounds(171, 111, 66, 21);  
            frame.getContentPane().add(tfb);  
            tfb.setColumns(10);  

            tfa = new JTextField();  
            tfa.setText("2");  
            tfa.setBounds(74, 111, 66, 21);  
            frame.getContentPane().add(tfa);  
            tfa.setColumns(10);  

            tfadd = new JTextField();  
            tfadd.setEditable(false);  
            tfadd.setBounds(286, 111, 66, 21);  
            frame.getContentPane().add(tfadd);  
            tfadd.setColumns(10);  

            tfn = new JTextField();  
            tfn.setText("10");  
            tfn.setBounds(74, 142, 66, 21);  
            frame.getContentPane().add(tfn);  
            tfn.setColumns(10);  

            tffactorial = new JTextField();  
            tffactorial.setEditable(false);  
            tffactorial.setBounds(286, 142, 66, 21);  
            frame.getContentPane().add(tffactorial);  
            tffactorial.setColumns(10);  
        }  
    }  

OK一切就緒!

2 測試

運行程序

通過JNA調用DLL超詳細代碼實戰

我們可以看到 DLL已經成功的工作了

相信大家已經學會如何用了吧!

來自:http://blog.csdn.net/gcangle/article/details/8504629

 本文由用戶 jopen 自行上傳分享,僅供網友學習交流。所有權歸原作者,若您的權利被侵害,請聯系管理員。
 轉載本站原創文章,請注明出處,并保留原始鏈接、圖片水印。
 本站是一個以用戶分享為主的開源技術平臺,歡迎各類分享!