JNA实现Java调用C++

本文详述了使用JNA(Java Native Access)在Java中调用C++ SDK的过程,包括依赖集成、C++动态库加载、基本数据类型及指针映射、结构体处理等关键步骤,并提供了实例说明。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

场景

公司有一个C++的SDK需要调用,本人是Java开发,所以使用JNA调用C++,在这里分享一些JNA的使用经验供大家参考

JNA介绍

JNA是JNI的封装升级,但是JNI的使用比较繁琐,有兴趣的可以自行了解
JNA官网地址:链接地址

如何使用JNA

  1. 集成JNA包
<dependency>
  	<groupId>net.java.dev.jna</groupId>
 	<artifactId>jna</artifactId>
 	<version>4.5.2</version>
</dependency>
<dependency>
  	<groupId>net.java.dev.jna</groupId>
  	<artifactId>jna-platform</artifactId>
  	<version>4.5.2</version>
</dependency>
  1. 创建接口并继承Library接口,加载C++动态连接库
package com.yxsd.cloud.transfer.library;

import com.sun.jna.Library;
import com.sun.jna.Native;
import com.sun.jna.ptr.PointerByReference;

public interface TestLibrary extends Library{
	
	TestLibrary INSTANCE = Native.loadLibrary("test",TestLibrary.class);

	int add(int a,int b);
}

Native.loadLibrary用来加载C++动态连接库
接口中的方法需要对应C++的方法(参数也需要对应)

  1. 调用接口执行方法
int add = TestLibrary.INSTANCE.add(1, 2);

整体来说使用JNA就是在接口中加载C++动态连接库并对应C++的方法,然后通过接口调用方法即可、

JNA的方法映射

基本数据类型

基本数据类型比较简单,可以参考下面的图片(图片来源于JNA官网)
图片来自JNA官网

指针映射

Java中是没有指针概念的,JNA中用Point映射C++指针,一般情况下一级指针用Point,二级指针用PointerByRefrence,不同的数据类型,指针映射的情况也不一样

通过C++的方法和Java中对应的方法来熟悉指针

C++中的方法:

void GetListTest(name, number, ier)
char** name;
int* number;
long* ier;

JNA方法映射


void GetListTest(PointerByReference name,IntByReference number,LongByReference ier);

C++中char**是二级指针,JNA中用PointerByReference映射
C++中int*是一级指针,JNA中用IntByReference,如果这个一级指针数据类型是long,则用PointerByReference对应

建议大家去了解一下C++的指针,这样方便大家理解JNA中的pointer,比如char**的数据类型就相当于Java的字符串数组

结构体映射

C++中的结构体类似于Java中的实体类,但在Jna中java实体类的每个属性都要与C++结构体的每一个字段对应

C++结构体

typedef struct _testStruct
   {
      char   id[18];                         
      char   name[48];              
      int    intValue;                    
      float  floatValue;
      long   longValue;
   } testStruct_t;

Java实体类

public class TestStruct extends Structure{
	public byte[] id = new byte[18];
	public byte[] name = new byte[48];
	public int intValue;
	public float floatValue;
	public NativeLong longValue;

	@Override
	protected List<String> getFieldOrder() {
		// TODO Auto-generated method stub
		return Arrays.asList(new String[] {
			"id",
			"name",
			"intValue",
			"floatValue",
			"longValue"
		});
	}
    public static class ByReference extends TestStruct implements Structure.ByReference {}
    public static class ByValue extends TestStruct implements Structure.ByValue {}
}

char[12]在JNA中需要用Java的byte[12],并且长度也是需要对应的,否则数据会发生错乱。getFieldOrder方法中必须按照顺序写出每个属性名,否则此实体类也是错误的。Structure.ByReference表示结构体的指针,Structure.ByValue表示结构体的值。

JNA总结

JNA的封装很便于Java对C++进行调用了,但是仍然处理不了一些问题,比如,C++的类是在JNA中无法体现的。各位如果想熟练使用JNA的话,建议各位了解一下Java和C++的一些基础知识,毕竟两种编程语言的思想还是有所不同的。

以上的介绍只是对JNA的一些简单使用,更复杂的方法调用不再过多演示,万变不离其宗,原理是一样的,如有问题,欢迎留言讨论。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值