通过JNA调用DLL超详细代码实战

jopen 10年前

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