java 根据类型映射java,java的映射

  java 根据类型映射java,java的映射

  00-1010 TypeMapperNativeMapped摘要的性质介绍

  00-1010 JNA有很多种映射,比如库映射,函数映射,函数参数和返回值映射。libary和function之间的映射相对简单,我们在上一篇文章中已经解释过了。对于类型映射,由于JAVA中有很多类型,这里我们将提取JNA的类型映射,单独说明。

  00-1010我们之前提到过,有两种方法可以映射JAVA中的方法和JNA的原生库。一种方式称为接口映射,另一种方式称为直接映射。

  但是我们考虑过这两种映射的本质是什么吗?

  比如native有一个方法。我们如何将JAVA代码中的方法参数传递给原生方法,并将原生方法的返回值转换成JAVA中函数的返回类型?

  答案是序列化。

  因为本质上所有的相互作用都是二元相互作用。最简单的情况,JAVA类型和native类型底层的数据长度是一样的,这样数据转换更容易。

  我们来看看JAVA类型和native类型之间的映射和长度关系:

  typenative类型Java Typechar8位整数bytewchar_t和与平台相关的charshort16位整数shortint32位整数intintboolean枚举类型int(正常情况下)longlonglong,__int6464位整数longfloat32位浮点数floatdouble64位浮点数doublepointer(例如void*)平台相关缓冲区指针(例如void *),数组平台相关[](基元类型数组)

  以上JAVA类型都是JDK自己的类型(指针除外)。

  除了JAVA自己的类型映射,JNA还定义了一些数据类型,可以用原生类型进行映射:

  Type c本机类型Java Typelong的含义与平台相关(32位或64位整数)nativelong char * string(本机编码或jna . encoding)String const wchar _ t * String(unicode)wstring char * * String数组String[]wchar_t** string数组(unicode)wstring[]void * * pointers数组指针[]struct* struct结构指针和结构结构union结构Unionstruct[]数组结构[]void (*FP)()函数指针(Java或本机)Callbackpointer (*)指针指针类型其他整数

  00-1010除了已定义的映射关系,您还可以使用TypeMapper来自定义参数类型。我们先来看看TypeMapper的定义:

  公共接口type mapper { FromNativeConverter getFromNativeConverter(Class?javaType);ToNativeConverter getToNativeConverter(类?javaType);}TypeMapper是一个接口,定义了两个转换器方法,分别是getFromNativeConverter和getToNativeConverter。

  如果要使用TypeMapper,需要实现,这两个方法就够了。让我们来看看官方的W32APITypeMapper是如何实现的:

  type converter string converter=new type converter(){ @ Override public Object to native(Object value,ToNativeContext context){ if(value==null)返回null;if(字符串的值实例[]) {

   return new StringArray((String[])value, true); } return new WString(value.toString()); } @Override public Object fromNative(Object value, FromNativeContext context) { if (value == null) return null; return value.toString(); } @Override public Class<?> nativeType() { return WString.class; } }; addTypeConverter(String.class, stringConverter); addToNativeConverter(String[].class, stringConverter);首先定义一个TypeConverter,在TypeConverter中实现了toNative,fromNative和nativeType三个方法。在这个例子中,native type是WString,而JAVA type是String。而这个TypeConverter就是最终要使用的FromNativeConverter和ToNativeConverter。

  有了typeMapper,应该怎么使用呢?最简单的方法就是将其添加到Native.load的第三个参数中,如下所示:

  

 TestLibrary lib = Native.load("testlib", TestLibrary.class, Collections.singletonMap(Library.OPTION_TYPE_MAPPER, mapper));

 

  

NativeMapped

TypeMapper需要在调用Native.load方法的时候传入,从而提供JAVA类型和native类型的转换关系。TypeMapper可以看做是类型转换关系的外部维护者。

 

  可能很多朋友已经想到了,既然能在JAVA类型外部维护转换关系,那么可不可以在JAVA类型本身对这个转换关系进行维护呢?答案是肯定的,我们只需要在要实现转换类型关系的JAVA类型实现NativeMapped接口即可。

  先来看下NativeMapped接口的定义:

  

public interface NativeMapped { Object fromNative(Object nativeValue, FromNativeContext context); Object toNative(); Class<?> nativeType();}

可以看到NativeMapped中定义要实现的方法基本上和FromNativeConverter、ToNativeConverter中定义的方法一致。

 

  下面举一个具体的例子来说明一下NativeMapped到底应该怎么使用。首先我们定义一个enum类实现NativeMapped接口:

  

 public enum TestEnum implements NativeMapped { VALUE1, VALUE2; @Override public Object fromNative(Object nativeValue, FromNativeContext context) { return values()[(Integer) nativeValue]; } @Override public Object toNative() { return ordinal(); } @Override public Class<?> nativeType() { return Integer.class; } }

这个类实现了从Integer到TestEnum枚举的转换。

 

  要想使用该TestEnum类的话,需要定义一个interface:

  

 public static interface EnumerationTestLibrary extends Library { TestEnum returnInt32Argument(TestEnum arg); }

具体调用逻辑如下:

 

  

EnumerationTestLibrary lib = Native.load("testlib", EnumerationTestLibrary.class);assertEquals("Enumeration improperly converted", TestEnum.VALUE1, lib.returnInt32Argument(TestEnum.VALUE1));assertEquals("Enumeration improperly converted", TestEnum.VALUE2, lib.returnInt32Argument(TestEnum.VALUE2));

可以看到,因为NativeMapped中已经包含了类型转换的信息,所以不需要再指定TypeMapper了。

 

  

注意,这里用到了testlib,这个testlib是从JNA的native模块中编译出来的,如果你是MAC环境的话可以拷贝JNA代码,运行ant native即可得到,编译完成之后,将这个libtestlib.dylib拷贝到你项目中的resources目录下面darwin-aarch64或者darwin-x86即可。

 

  

有不会的同学,可以联系我。

 

  

 

  

总结

本文讲解了JNA中的类型映射规则和自定义类型映射的方法。

 

  本文的代码:https://github.com/ddean2009/learn-java-base-9-to-20

  到此这篇关于java高级用法之JNA中使用类型映射的文章就介绍到这了,更多相关JNA 类型映射内容请搜索盛行IT以前的文章或继续浏览下面的相关文章希望大家以后多多支持盛行IT!

郑重声明:本文由网友发布,不代表盛行IT的观点,版权归原作者所有,仅为传播更多信息之目的,如有侵权请联系,我们将第一时间修改或删除,多谢。

留言与评论(共有 条评论)
   
验证码: