博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Android开发实践:JNI函数签名生成器
阅读量:6983 次
发布时间:2019-06-27

本文共 3099 字,大约阅读时间需要 10 分钟。

    “函数签名”在Android NDK开发中很常见,由于Java支持重载,仅靠函数名无法唯一确定一个方法。因此,JNI提供了一套签名规则,用一个字符串来唯一确定一个Java端定义的Native方法。

     具体每一种Java数据类型对应的签名字符串如下所示(来自Oracle官网JNI的介绍):

    

    原理其实并不复杂,每种基本类型对应一个单字符签名,而类则对应为"L"+类的全路径+";",数组类型则对应"["+元素类型的签名,函数的签名则是:(各参数类型签名)+ 返回类型的签名。

    搞清楚了基本原理,我们就可以尝试自定义一个Java工具类,为Java的Native函数生成签名字符串了,具体代码如下:

    

/* *  COPYRIGHT NOTICE   *  Copyright (C) 2014, ticktick 
 *  http://ticktick.blog.51cto.com/ *    *  @license under the Apache License, Version 2.0  * *  @file    SignatureGen.java *  @brief   Implement a java class for jni signature generate *   *  @version 1.0      *  @author  ticktick *  @date    2014/12/15   *  */package com.ticktick.library;import java.util.HashMap;public class SignatureGen {    public static final HashMap
 Primitives = new HashMap
();     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");     }             public static String getSignature( Class ret, Class...params ) {        StringBuilder builder = new StringBuilder();        builder.append("(");        for( Class param : params ) {            builder.append(getSignature(param));         }         builder.append(")");        builder.append(getSignature(ret));        return builder.toString();    }     protected static String getSignature( Class param ) {         StringBuilder builder = new StringBuilder();        String name = "";        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(".","/")+";");        }           return builder.toString();    }}

    该SignatureGen类提供一个支持变参的函数getSignature来获取一个Java函数的签名字符串,第一个参数为函数返回值类型的class对象,变参为每一个函数参数类型的class对象

    具体用法示例如下,打印出不同类型的函数的签名字符串。

Log.d("Signature","void func() --> " + SignatureGen.getSignature(Void.class));Log.d("Signature","boolean func() --> " + SignatureGen.getSignature(Boolean.class));Log.d("Signature","int func(boolean a) --> " + SignatureGen.getSignature(Integer.class,Boolean.class));Log.d("Signature","int func(boolean a,String b) --> " + SignatureGen.getSignature(Integer.class,Boolean.class,String.class));Log.d("Signature","int func(byte[] c) --> " + SignatureGen.getSignature(Integer.class,Byte[].class));		Log.d("Signature","long func(int n,String str,int arr) -->" + SignatureGen.getSignature(Long.class,Integer.class,String.class,Integer[].class));

    输出结果截屏如下:

    

    

    关于JNI函数签名生成器就介绍到这儿了,原理并不复杂所以我也没有进行过多的分析,希望这个工具类能够在大家今后的项目中派上用场,有任何疑问欢迎留言或者来信lujun.hust@gmail.com交流,或者关注我的新浪微博 获取最新的文章和资讯。

转载地址:http://ljvpl.baihongyu.com/

你可能感兴趣的文章
Arimo利用Alluxio的内存能力提升深度学习模型的结果效率(Time-to-Result)
查看>>
代号“沙尘暴”:黑客剑指日本关键基础设施
查看>>
光纤光缆市场需求高于预期 我国将迎来流量经济
查看>>
晶科能源与森源电气签订300MW光伏组件供货协议
查看>>
中国电信发布转型升级战略:构建一横四纵生态圈
查看>>
全渠道的核心是渠道协同和数据整合
查看>>
“小会话,大学问” - 如何让聊天机器人读懂对话历史?| 论文访谈间 #03
查看>>
让问答更自然 - 基于拷贝和检索机制的自然答案生成系统研究 | 论文访谈间 #02...
查看>>
首航节能:光热行业刚起步 子公司处于亏损状态
查看>>
《PHP精粹:编写高效PHP代码》——第1章面向对象编程
查看>>
美国智能家居止步不前 原因是产品过于碎片化
查看>>
大数据到底是不是“算命”?技术大牛们这样说
查看>>
让智能家居产品操控更简单 快捷键来了
查看>>
《面向对象分析与设计》一3.2 参与者
查看>>
WCF 性能基准报告
查看>>
智迪科技携手海通安恒,启动SAP实施项目
查看>>
机器学习算法在自动驾驶领域的应用大盘点!
查看>>
《深入理解Android:Telephony原理剖析与最佳实践》一1.1 智能手机的系统结构
查看>>
卡斯特罗的离去对古巴科技产业的未来有何影响?
查看>>
维护网络安全要攻防兼备
查看>>