您好,登錄后才能下訂單哦!
“函數簽名”在Android NDK開發中很常見,由于Java支持重載,僅靠函數名無法唯一確定一個方法。因此,JNI提供了一套簽名規則,用一個字符串來唯一確定一個Java端定義的Native方法。
具體每一種Java數據類型對應的簽名字符串如下所示(來自Oracle官網JNI的介紹):
原理其實并不復雜,每種基本類型對應一個單字符簽名,而類則對應為"L"+類的全路徑+";",數組類型則對應"["+元素類型的簽名,函數的簽名則是:(各參數類型簽名)+ 返回類型的簽名。
搞清楚了基本原理,我們就可以嘗試自定義一個Java工具類,為Java的Native函數生成簽名字符串了,具體代碼如下:
/* * COPYRIGHT NOTICE * Copyright (C) 2014, ticktick <lujun.hust@gmail.com> * 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<String,String> Primitives = new HashMap<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"); } 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交流,或者關注我的新浪微博 @盧_俊 獲取最新的文章和資訊。
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。