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