通过JNA调用DLL超详细代码实战
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即可
1 使用步骤
1.1 编写DLL
这里我们使用 code::blocks编写dll
首先新建一个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是动态链接库的入口函数我们不用管它,点击编译按钮
这样就生成了DLL文件了,我们在项目文件夹 bin文件夹下的Debug中可以找到编译成了DLL文件,将这个文件拷贝到需要使用DLL的JAVA工程路径下
这样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 测试
运行程序
我们可以看到 DLL已经成功的工作了
相信大家已经学会如何用了吧!
来自:http://blog.csdn.net/gcangle/article/details/8504629