范文健康探索娱乐情感热点
投稿投诉
热点动态
科技财经
情感日志
励志美文
娱乐时尚
游戏搞笑
探索旅游
历史星座
健康养生
美丽育儿
范文作文
教案论文
国学影视

java高级用法之JNA类型映射应该注意的问题

  简介
  JNA提供JAVA类型和native类型的映射关系,但是这一种映射关系只是一个大概的映射,我们在实际的应用中还有很多需要注意的事项,本文将会为大家详细讲解在使用类型映射中可能会出现的问题。一起来看看吧。 String
  首先是String的映射,JAVA中的String实际上对应的是两种native类型:const char* 和 const wchar_t 。默认情况下String会被转换成为char  。
  char是ANSI类型的数据类型,而wchar_t是Unicode字符的数据类型,也叫做宽字符。
  如果JAVA的unicode characters要转换成为char数组,那么需要进行一些编码操作,如果设置了jna.encoding,那么就会使用设置好的编码方式来进行编码。默认情况下编码方式是 "UTF8".
  如果是WString,那么Unicode values可以直接拷贝到WString中,而不需要进行任何编码。
  先看一个简单的例子:  char* returnStringArgument(char *arg) {   return arg; }  wchar_t* returnWStringArgument(wchar_t *arg) {   return arg; }
  上面的native代码可以映射为: String returnStringArgument(String s); WString returnWStringArgument(WString s);
  再来看一个不同的例子,假如native方法的定义是这样的: int getString(char* buffer, int bufsize);  int getUnicodeString(wchar_t* buffer, int bufsize);
  我们定义了两个方法,方法的参数分别是char* 和wchar_t*。
  接下来看一下怎么在JAVA中定义方法的映射: // Mapping A: int getString(byte[] buf, int bufsize); // Mapping B: int getUnicodeString(char[] buf, int bufsize);
  下面是具体的使用: byte[] buf = new byte[256]; int len = getString(buf, buf.length); String normalCString = Native.toString(buf); String embeddedNULs = new String(buf, 0, len);
  可能有同学会问了,既然JAVA中的String可以转换成为char*,为什么这里需要使用byte数组呢?
  这是因为getString方法需要对传入的char数组中的内容进行修改,但是因为String是不可变的,所以这里是不能直接使用String的,我们需要使用byte数组。
  接着我们使用Native.toString(byte[]) 将byte数组转换成为JAVA字符串。
  再看一个返回值的情况: // Example A: Returns a C string directly const char* getString(); // Example B: Returns a wide character C string directly const wchar_t* getString();
  一般情况下,如果是native方法直接返回string,我们可以使用String进行映射: // Mapping A String getString(); // Mapping B WString getString();
  如果native code为String分配了内存空间,那么我们最好使用JNA中的Pointer作为返回值,这样我们可以在未来某些时候,释放所占用的空间,如下所示: Pointer getString(); Buffers,Memory,数组和Pointer
  什么时候需要用到Buffers和Memory呢?
  一般情况下如果是基础数据的数组作为参数传到函数中的话,可以在JAVA中直接使用基础类的数组来替代。但是如果native方法在方法返回之后,还需要访问数组的话(保存了指向数组的指针),这种情况下使用基础类的数组就不太合适了,这种情况下,我们需要用到ByteBuffers或者Memory。
  我们知道JAVA中的数组是带有长度的,但是对于native方法来说,返回的数组实际上是一个指向数组的指针,我们并不能知道返回数组的长度,所以如果native方法返回的是数组指针的话,JAVA代码中用数组来进行映射就是不合适的。这种情况下,需要用到Pointer.
  Pointer表示的是一个指针,先看一下Pointer的例子,首先是native代码: void* returnPointerArgument(void *arg) {   return arg; }  void* returnPointerArrayElement(void* args[], int which) {   return args[which]; }
  接下来是JAVA的映射: Pointer returnPointerArgument(Pointer p);  Pointer returnPointerArrayElement(Pointer[] args, int which);
  除了基本的Pointer之外,你还可以自定义带类型的Pointer,也就是PointerType. 只需要继承PointerType即可,如下所示: public static class TestPointerType extends PointerType {             public TestPointerType() { }             public TestPointerType(Pointer p) { super(p); }         } TestPointerType returnPointerArrayElement(TestPointerType[] args, int which);
  再看一下字符串数组: char* returnStringArrayElement(char* args[], int which) {   return args[which]; }  wchar_t* returnWideStringArrayElement(wchar_t* args[], int which) {   return args[which]; }
  对应的JAVA映射如下: String returnStringArrayElement(String[] args, int which);  WString returnWideStringArrayElement(WString[] args, int which);
  对应Buffer来说,JAVA NIO中提供了很多类型的buffer,比如ByteBuffer,ShortBuffer,IntBuffer,LongBuffer,FloatBuffer和DoubleBuffer等。这里以ByteBuffer为例,来看一下具体的使用.
  首先看下native代码: int32_t fillInt8Buffer(int8_t *buf, int len, char value) {   int i;    for (i=0;i < len;i++) {     buf[i] = value;   }   return len; }
  这里将buff进行填充,很明显后续还需要使用到这个buffer,所以这里使用数组是不合适的,我们可以选择使用ByteBuffer: int fillInt8Buffer(ByteBuffer buf, int len, byte value);
  然后看下具体怎么使用: TestLibrary lib = Native.load("testlib", TestLibrary.class);          ByteBuffer buf  = ByteBuffer.allocate(1024).order(ByteOrder.nativeOrder());         final byte MAGIC = (byte)0xED;         lib.fillInt8Buffer(buf, 1024, MAGIC);         for (int i=0;i < buf.capacity();i++) {             assertEquals("Bad value at index " + i, MAGIC, buf.get(i));         } 可变参数
  对于native和JAVA本身来说,都是支持可变参数的,我们举个例子,在native方法中: int32_t addVarArgs(const char *fmt, ...) {   va_list ap;   int32_t sum = 0;   va_start(ap, fmt);    while (*fmt) {     switch (*fmt++) {     case "d":       sum += va_arg(ap, int32_t);       break;     case "l":       sum += (int) va_arg(ap, int64_t);       break;     case "s": // short (promoted to "int" when passed through "...")      case "c": // byte/char (promoted to "int" when passed through "...")       sum += (int) va_arg(ap, int);       break;     case "f": // float (promoted to ‘double’ when passed through ‘...’)     case "g": // double       sum += (int) va_arg(ap, double);       break;     default:       break;     }   }   va_end(ap);   return sum; }
  对应的JAVA方法映射如下: public int addVarArgs(String fmt, Number... args);
  相应的调用代码如下: int arg1 = 1; int arg2 = 2; assertEquals("32-bit integer varargs not added correctly", arg1 + arg2,                      lib.addVarArgs("dd", arg1, arg2)); 总结
  本文介绍了在使用JNA方法映射中应该注意的一些细节和具体的使用问题。
  本文的代码:https://github.com/ddean2009/learn-java-base-9-to-20.git 本文已收录于 http://www.flydean.com/05-jna-type-mapping-details-md/
  最通俗的解读,最深刻的干货,最简洁的教程,众多你不知道的小技巧等你来发现!
  欢迎关注我的公众号:「程序那些事」,懂技术,更懂你!

荣耀手机哪一款比较好用?用过V10,V20,20,现在正在用荣耀30PRO,个人感觉,荣耀30pro是荣耀目前最好用的手机,拍照,系统(鸿蒙)NFC,红外,双扬声器,无线充电,该有的都有了,也是荣耀最后一哪个数据可视化工具比较好?看了一下其他的回答,都是利用现有的可视化软件,这里以Python为例,介绍2个比较好用的可视化包seaborn和pyecharts,简单易学容易上手,绘制的图形漂亮大方整洁,感兴趣高通骁龙625与435相比,在性能上能差多少?在几大手机处理器品牌方面,可谓当属高通是最大的厂商用户群体。我们知道高通除了在旗舰芯片方面表现非常出色之外,在中端领域也是诸多厂商喜欢选择的一块。熟悉高通骁龙系列的朋友都知道,高通任正非,马云,会如何看待联想爆雷事件?会不会跟小市民见解不同?小市民应该不小。关于任正非,马云会如何看待联想爆雷事件?如我这等小市民揣测任正非豁达坦荡,心里无私天地宽。压根就没心思,没工夫,没兴趣去关注,去咀嚼联想的雷和雨,风和爆。任老人家会科技发展,我们的思考是不是越来越少?科技发展,我们的思考不是越来越少,而是越来越多。举个发生在我自己身上的例子。我是一名教师,因新型冠状肺炎,我们都是弹性上班,但听课不停学,停课不停研,学习研修照常进行,怎么进行?无杜虹是我国首位冷冻人,预计2065年复活,这项计划会成真吗?先问一下,目前有成功复活人工冻存活体动物的先例吗?比如实验大鼠或小鼠,再或者猫狗之类的。所谓复活冻存人体就是一个噱头。跟头颅异体移植的炒作事件一样,连高等哺乳动物头颅异体移植,甚至英伟达RTX206012G测试出炉非游戏性能表现出众本文转自IT之家作者孤城今晚,各大显卡厂商发布RTX206012G显卡,售价3999元。值得注意的上,目前上市的RTX206012G未标注LHR。现在,Pcmarket网站已经发布有线4G无缝切换,智能组网轻松简单蒲公英X4C上手测试从业多年,一直做线下活动相关工作,但是自疫情爆发以来,线下展会业务大幅萎缩,很多企业都将展会及发布会放到了线上。不管是展会还是发布会,亦或者是小型座谈会,都无一例外的离不开发言环节发明一个手机观察视力功能在我们的世界里,视力是我们的一个感觉器官,这个感觉器官是我们的一个非常重要的器官,这个器官的好坏能看出这个人对自己眼睛的好坏,所以要保护好自己的眼睛。眼睛的保护要时时观察,观察需要一只耳全聋,一只耳刚配了助听器,戴了后,近期耳朵里面闷闷的,像塞住了一样怎么回事?这个在听力学上叫做堵耳效应,其实我们正常情况下,如果把手指堵住耳道,也会出现自己说话声音变大的现象,佩戴上助听器自己说话的声音是通过骨传导放大,也就是通过颅骨的振动,别人说话的声音36氪首发网约工作平台小包智工获得盖雅工场战略投资,想要更好地结合BC两端36氪获悉,网约工作平台小包智工完成劳动力SaaS厂商盖雅工场的战略投资,上一轮融资是去年云歌智能的战略投资。小包智工成立于2017年,通过搭建服务于灵活就业者的网约工作平台,将B
LEDSMART隐私保护指引引言本应用(以下简称LEDSMART或谭桂兴)尊重并保护所有使用服务用户的个人隐私权。我们非常重视您的个人信息,并让您对个人信息拥有控制权,我们会使用强大的加密技术来保护您的隐私,燃油车和新能源汽车如何选择?近年来随着互联网和造车新势力的日益兴起及新能源汽车产业的突飞猛进,如特斯拉蔚来小鹏理想等为代表的新能源汽车给传统车带来了一定的冲击,也给消费者在购车的时候有了更多的选择,在面对新能CCV创始合伙人周炜我先是喜马拉雅的用户,后来才是喜马拉雅的投资人周炜连年名列福布斯中国最佳创投人TOP30,是喜马拉雅的第一位投资人创世伙伴资本CCV创始合伙人,从事VC投资十多年。高达30的独角兽命中率让周炜享誉创投圈,喜马拉雅京东商城京东数网友数博会数字生活数不尽的便捷来源原创稿作为全国首个大数据综合试验区全国第一个提出大数据发展战略行动的省份,贵州化茧成蝶,以大数据为引领重构后发地区整体发展方式,从一张白纸蜕变成大数据高地,成为大数据国家战略中小康股份年报研发投入超19亿元,营收占比11来源环球网4月29日晚间,小康股份(601127。SH)发布2021年度业绩报告。公告显示,2021年小康股份全年实现营业收入167。18亿元,同比增长16。89,年度研发投入达1flex不香吗,你还在傻傻地用float吗我是小渔歌,点击右上方关注,每天为你分享前端技术知识干货。大家在做移动端的时候,还有人在用浮动(float)布局吗?弹性盒模型(flex)可以解决一切,当你用熟悉了之后,你绝对不会12512G不到2499元!MotoedgeS30又降价买到不就是赚到?相信大家也看到了,现阶段不少国内手机厂商推出旗舰的价格是越来越往苹果靠齐了,各个都想冲刺高端,然而想要冲刺高端,可不仅仅是对标苹果价格那么简单的。据悉,2021年国内5000元以上欧盟给谷歌们再上紧箍咒来源人民网据报道,4月23日,欧盟成员国与欧洲议会的谈判代表就欧盟数字服务法达成一致。该法案要求互联网平台企业采取更多措施删除非法和有害的在线内容,否则可能面临巨额罚款。外媒普遍认宇宙中有多少颗恒星?比地球上的沙粒还要多得多宇宙有多大?没有边界!目前人类能观测到的范围,为930亿光年,这是一个可怕的数字。我们都知道,光速是目前已知的宇宙中最快的物质,每秒30万千米,一秒钟就能围绕地球转七圈半。但是,光从狂妄不羁的马斯克成就非凡,看科技创新生态的重要性近日,马斯克与推特公司达成440亿美元的收购意向。马斯克曾经的又一个狂言变为了现实。更诡吊的是,马斯克又在推特发文,宣布要收购可口可乐接下来我要收购可口可乐公司,再把可卡因重新加进字节再出王炸消息增资40亿字节潜伏7年,只为一件事布局金融版图。记者洛重阳编辑呦呦两年增资3次,从10亿到90亿元,字节跳动发展网贷业务的野心和决心在不断增长。4月27日,深圳市中融小额贷款有限公司(下称深