Android开发实践:JNI函数签名生成器
“函数签名”在Android NDK开发中很常见,由于Java支持重载,仅靠函数名无法唯一确定一个方法。因此,JNI提供了一套签名规则,用一个字符串来唯一确定一个Java端定义的Native方法。
具体每一种Java数据类型对应的签名字符串如下所示(来自Oracle官网JNI的介绍):
原理其实并不复杂,每种基本类型对应一个单字符签名,而类则对应为"L"+类的全路径+";",数组类型则对应"["+元素类型的签名,函数的签名则是:(各参数类型签名)+ 返回类型的签名。
搞清楚了基本原理,我们就可以尝试自定义一个Java工具类,为Java的Native函数生成签名字符串了,具体代码如下:
/**COPYRIGHTNOTICE*Copyright(C)2014,ticktick<lujun.hust@gmail.com>*http://ticktick.blog.51cto.com/**@licenseundertheApacheLicense,Version2.0**@fileSignatureGen.java*@briefImplementajavaclassforjnisignaturegenerate**@version1.0*@authorticktick*@date2014/12/15**/packagecom.ticktick.library;importjava.util.HashMap;publicclassSignatureGen{publicstaticfinalHashMap<String,String>Primitives=newHashMap<String,String>();static{Primitives.put(Void.class.getName(),"V");Primitives.put(Boolean.class.getName(),"Z");Primitives.put(Byte.class.getName(),"B");Primitives.put(Character.class.getName(),"C");Primitives.put(Short.class.getName(),"S");Primitives.put(Integer.class.getName(),"I");Primitives.put(Long.class.getName(),"J");Primitives.put(Float.class.getName(),"F");Primitives.put(Double.class.getName(),"D");}publicstaticStringgetSignature(Classret,Class...params){StringBuilderbuilder=newStringBuilder();builder.append("(");for(Classparam:params){builder.append(getSignature(param));}builder.append(")");builder.append(getSignature(ret));returnbuilder.toString();}protectedstaticStringgetSignature(Classparam){StringBuilderbuilder=newStringBuilder();Stringname="";if(param.isArray()){name=param.getComponentType().getName();builder.append("[");}else{name=param.getName();}if(Primitives.containsKey(name)){builder.append(Primitives.get(name));}else{builder.append("L"+name.replace(".","/")+";");}returnbuilder.toString();}}
该SignatureGen类提供一个支持变参的函数getSignature来获取一个Java函数的签名字符串,第一个参数为函数返回值类型的class对象,变参为每一个函数参数类型的class对象。
具体用法示例如下,打印出不同类型的函数的签名字符串。
Log.d("Signature","voidfunc()-->"+SignatureGen.getSignature(Void.class));Log.d("Signature","booleanfunc()-->"+SignatureGen.getSignature(Boolean.class));Log.d("Signature","intfunc(booleana)-->"+SignatureGen.getSignature(Integer.class,Boolean.class));Log.d("Signature","intfunc(booleana,Stringb)-->"+SignatureGen.getSignature(Integer.class,Boolean.class,String.class));Log.d("Signature","intfunc(byte[]c)-->"+SignatureGen.getSignature(Integer.class,Byte[].class));Log.d("Signature","longfunc(intn,Stringstr,intarr)-->"+SignatureGen.getSignature(Long.class,Integer.class,String.class,Integer[].class));
输出结果截屏如下:
关于JNI函数签名生成器就介绍到这儿了,原理并不复杂所以我也没有进行过多的分析,希望这个工具类能够在大家今后的项目中派上用场,有任何疑问欢迎留言或者来信lujun.hust@gmail.com交流,或者关注我的新浪微博 @卢_俊 获取最新的文章和资讯。
声明:本站所有文章资源内容,如无特殊说明或标注,均为采集网络资源。如若本站内容侵犯了原著者的合法权益,可联系本站删除。