【NDK】【005】JNA調用dll動態庫

什麼是JNA

  • JNA全稱Java Native Access,是JNI之外另一個Java訪問C++的混編框架
  • JNA非Java自帶功能,需要導入第三方類庫
  • JNA只支持Java調用C++,不支持C++調用Java
  • JNA對C++代碼和編譯無特殊要求,普通的C++代碼都可調用,非常方便
  • JNA直接將dll文件加載爲一個接口對象,只要定義一個接口,裏面包含和C++同名的方法即可,使用非常方便
  • JNA在Java和C++兩端編碼都十分方便,這正是它流行的原因
  • JNA的效率遠低於JNI,可達百倍之多,方便的同時帶來的必然是性能損失。但是偶爾調用影響並不大,所以它在大多時候仍是首選。在Java和C++互調非常頻繁的場景下,應當使用JNI

JNA調用DLL示例

JNA開發包下載地址:Java Native Access 5.5.0


	//hello.cpp

	#include <iostream>
	
	extern "C" __declspec(dllexport)
	void hello() {
	    std::cout << "Hello World" << std::endl;
	}
	
	extern "C" __declspec(dllexport)
	int sum(int a, int b) {
	    return a + b;
	}
	
	extern "C" __declspec(dllexport)
	void printMessage(wchar_t *message) {
	    std::wcout << message << std::endl;
	}


	//CMakeLists.txt

	project(hello)
	
	set(CMAKE_CXX_STANDARD 17)
	
	add_library(
	        hello SHARED
	        hello.cpp
	)


	//JnaHello.java

	package com.easing.java;
	
	import com.sun.jna.Library;
	import com.sun.jna.Native;
	import com.sun.jna.WString;
	
	public interface JnaHello extends Library {
	
	    JnaHello INSTANCE = Native.loadLibrary("libhello", JnaHello.class);
	
	    void hello();
	
	    void printMessage(WString message);
	
	    int sum(int a, int b);
	}


	//Hello.java

	package com.easing.java;
	
	import com.sun.jna.WString;
	
	public class Hello {
	
	    public static void main(String[] args) {
	        JnaHello.INSTANCE.hello();
	        JnaHello.INSTANCE.printMessage(new WString("JNA Demo"));
	        int sum = JnaHello.INSTANCE.sum(100, 300);
	        System.out.println("sum result is " + sum);
	    }
	}

JNA Class類型

只要定義一個Java類,實現Structure接口,即可對應C++中的class/struct類型

JNA類型對照表

Java Type Native Type
int int
Native Long long
double double
boolean int
byte char
char wchar_t
String char*
WString wchar_t*
array pointer array
Buffer/Pointer void*
String[] char**
WString[] wchar_t**
Structure struct
Callback (*pFunc)()

JNA使用注意事項

  • 中文字符要使用WString,在C++中要通過printf或wcout打印,cout無法打印中文
  • 在IntelliJ Idea中,JNA會從Source和Resource目錄中查找dll(可右鍵文件夾,通過Make Directory as菜單設置目錄種類,見下圖),注意dll放置的位置
  • 打包成Jar包後,JNA會從運行目錄和操作系統的path環境變量中查找dll,將dll放在Jar包同目錄下,或者任意一個path目錄下,均可以
  • 如果C++使用到了iostream等C++標準庫,則需要依賴C++ std相關的dll,如果你的電腦上所有path目錄下均不存在這些dll,則會報錯,可以手動下載std支持庫來解決,放到工程dll相同位置即可
  • C++標準庫相關dll下載:JNA C++ Std Support Library
    在這裏插入圖片描述
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章