【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
    在这里插入图片描述
发布了442 篇原创文章 · 获赞 45 · 访问量 15万+

猜你喜欢

转载自blog.csdn.net/u013718730/article/details/104453713