JNA--Java呼叫DLL
1、 起源
Java原生的呼叫本地函式(C/C++)的機制是JNI(JavaNative Interface),但是由於其使用的複雜,還需要寫C程式碼,對許多入門級程式設計師來說實在不是個好的選擇。JNA(Java Native Access)是Sun公司主導開發的基於JNI的java呼叫原生函式的機制,是對JNI的再次封裝。其優點是,使用簡單,只需要編寫一個包含指定函式的介面即可。JNA提供了動態的C 語言編寫的轉發器,可以自動實現Java 和C 的資料型別對映。而不必像使用JNI一樣完全自己去做資料型別對映,不再需要編寫那個煩人的C 動態連結庫。當然,JNA相比於JNI,效率不高,會有部分效能損失,畢竟是對JNI的擴充套件。類似的優秀框架還有JNative。
2、 資料型別對映(來源於JNA的官方JavaDoc文件首頁)
Java types must be chosen to match native types of the samesize. Following are the types supported by the JNA library. (簡單型別對映)
Java Type |
C Type |
Native Representation |
boolean |
int |
32-bit integer (customizable) |
byte |
char |
8-bit integer |
char |
wchar_t |
platform-dependent |
short |
short |
16-bit integer |
int |
int |
32-bit integer |
long |
long long, __int64 |
64-bit integer |
float |
float |
32-bit floating point |
double |
double |
64-bit floating point |
pointer |
platform-dependent (32- or 64-bit pointer to memory) |
|
<T>[] (array of primitive type) |
pointer |
32- or 64-bit pointer to memory (argument/return) |
In addition to the above types, which aresupported at the native layer, the JNA Java library automatically handles thefollowing types. All but
NativeMapped
and
NativeLong
are converted to
Pointer
before being passed to the native layer.(複雜型別對映)
char* |
NUL-terminated array (native encoding or jna.encoding) |
|
wchar_t* |
NUL-terminated array (unicode) |
|
char** |
NULL-terminated array of C strings |
|
wchar_t** |
NULL-terminated array of wide C strings |
|
struct* |
pointer to struct (argument or return) (or explicitly) |
|
union |
same as Structure |
|
struct[] |
array of structs, contiguous in memory |
|
<T> (*fp)() |
function pointer (Java or native) |
|
varies |
depends on definition |
|
long |
platform-dependent (32- or 64-bit integer) |
|
pointer |
same as Pointer |
3、 Eclipse中使用DLL
在Eclipse中,匯入JNA的jar包(如jna-3.5.1.jar),在需要使用DLL的專案的根目錄下放置.dll檔案,使用例子如下:
Dll檔案為:MyDll.dll,其中申明的外部可呼叫方法有:
void add1(int a,int b);
void add2(int *a,int*b);//a和b是指向int型的指標
void add3(int *a,int *b);//a和b是指向int[]的指標
void add4(int a[],int b[]);
對應的java檔案JNATest.java:
importcom.sun.jna.ptr.IntByReference;
public interface JNATestextends Library {
JNATest JNATestIntance = (JNATest) Native.loadLibrary(
" MyDll ", JNATest.class);
//c中的函式void add1(int a,int b);
public void add1(int a,int b);
//void add2(int *a,int*b);//a和b是指向int型的指標
public void add2(IntByReference a,IntByReference b);
//void add3(int *a,int *b);//a和b是指向int[]的指標
public void add3(int []a,int []b);
//void add4(int a[],int b[]);
public void add4(int []a,int []b);
public static void main(String args[])
{
int a=9;
int b=4;
int array1={1,4,5};
int array2={3,1,5};
JNATest.JNATestIntance.add1(a,b);
JNATest.JNATestIntance.add2(newIntByReference(a),new IntByReference(b));
JNATest.JNATestIntance.add3(array1,array2);
JNATest.JNATestIntance. add4(array1,array2);
}
}
其中IntByReference在表示指向int型的指標,類似的還有ByteByReference, DoubleByReference,
FloatByReference,LongByReference, NativeLongByReference, PointerByReference,ShortByReference,
W32API.HANDLEByReference, X11.AtomByReference,X11.WindowByReference
PointerByReference 類表示指向指標的指標。
當然,涉及指標時也可以使用Pointer這個類,它是一個單例,不允許用建構函式建立。可以使用PointerType自定義。具體實現參考JavaDoc文件。Pointer使用:
import com.sun.jna.ptr.IntByReference;
public interface JNATestextends Library {
JNATest JNATestIntance = (JNATest) Native.loadLibrary(
"Sense2020Dll", JNATest.class);
//c中的函式void add1(int a,int b);
public void add1(int a,int b);
//void add2(int *a,int*b);//a和b是指向int型的指標
public void add2(Pointer a,Pointer b);
public static void main(String args[])
{
int a=9;
int b=4;
JNATest.JNATestIntance.add1(a,b);
JNATest.JNATestIntance.add2(newIntByReference(a). getPointer(),
newIntByReference(b). getPointer());
}
}
相關文章
- exe呼叫DLL的方式
- Nodejs如何呼叫Dll模組NodeJS
- C# 生成DLL 並 呼叫C#
- php 呼叫dll 裡面的方法PHP
- VS2012生成C的dll並呼叫以及Python呼叫C的DLLPython
- C#呼叫 C++的DLLC#C++
- C++呼叫 c#生成的dllC++C#
- java呼叫DLL,呼叫北洋印表機列印二維碼標籤Java
- JAVA呼叫C語言下的DLL檔案JavaC語言
- VS中呼叫DLL動態庫的方法
- java中呼叫dll檔案的步驟Java
- 使用使用rundll32 呼叫指定dll的方法
- C++呼叫C#的動態庫dllC++C#
- c#呼叫C++DLL EntryPointNotFoundException 找不到入口點C#C++Exception
- 【混合程式設計】C/C++呼叫Fortran的DLL程式設計C++
- P/Invoke之C#呼叫動態連結庫DLLC#
- C# 呼叫 C++ 生成的 dll 關鍵實現部分C#C++
- Sql Server 資料庫中呼叫dll檔案的過程SQLServer資料庫
- 如何建立Electron + Vue3專案, 並呼叫C# dllVueC#
- NX二次開發-C#使用DllImport呼叫libufun.dll裡的UF函式(反編譯.net.dll)呼叫loop等UF函式C#Import函式編譯OOP
- VS(visual studio) C++ 封裝dll,以及其隱式呼叫與顯式呼叫(靜態動態)C++封裝
- lua——alien庫實現lua呼叫C動態連結庫(dll、so)
- Python搭建呼叫本地dll的Windows服務(瀏覽器可以訪問,附測試dll64位和32位檔案)PythonWindows瀏覽器
- dll內申請的記憶體可以由呼叫它的程式釋放嗎?記憶體
- windows和linux gcc生成動態連結庫DLL和SO並用python呼叫WindowsLinuxGCPython
- c# 呼叫 C++ dll 傳入傳出型別對應說明(轉)C#C++型別
- 低版本的.netFramework專案呼叫高版本的.net framework的dll的解決方法Framework
- 全方位解讀DLL檔案—編寫DLL
- VS如何將核心函式封裝成dll、lib,並供給第三方呼叫?函式封裝
- 實現通過COM元件方式實現java呼叫C#寫的DLL檔案的完整demo元件JavaC#
- 簡單架構:採集庫dll、檢測演算法dll、專案程式exe,框架庫dll架構演算法框架
- Could not load dynamic library ‘cublas64_10.dll‘; dlerror: cublas64_10.dll not found或者缺少DLL問題Error
- 深入解析DLL劫持漏洞
- 程式注入之DLL注入
- DLL劫持並使用MinHookHook
- 【Intellij IDEA】開啟IDEA時錯誤:Failed to load JVM DLL ...\jvm.dllIntelliJIdeaAIJVM
- dll反編譯(修改引用檔案、修改程式碼)再生成dll編譯
- WAMP 安裝——缺少檔案(VCRUNTIME140.DLL、API-MS-WIN-CRT-RUNTIME-L1-1-0.DLL、MSVCR110.DLL)API
- 沒有找到MFC80UD.DLL"沒有找到MFC80UD.DLL,