通過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