溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務(wù)條款》

Android開發(fā)實踐:JNI函數(shù)簽名生成器

發(fā)布時間:2020-08-11 00:11:10 來源:網(wǎng)絡(luò) 閱讀:3477 作者:Jhuster 欄目:移動開發(fā)

    “函數(shù)簽名”在Android NDK開發(fā)中很常見,由于Java支持重載,僅靠函數(shù)名無法唯一確定一個方法。因此,JNI提供了一套簽名規(guī)則,用一個字符串來唯一確定一個Java端定義的Native方法。


     具體每一種Java數(shù)據(jù)類型對應(yīng)的簽名字符串如下所示(來自O(shè)racle官網(wǎng)JNI的介紹):


    Android開發(fā)實踐:JNI函數(shù)簽名生成器


    原理其實并不復(fù)雜,每種基本類型對應(yīng)一個單字符簽名,而類則對應(yīng)為"L"+類的全路徑+";",數(shù)組類型則對應(yīng)"["+元素類型的簽名,函數(shù)的簽名則是:(各參數(shù)類型簽名)+ 返回類型的簽名。


    搞清楚了基本原理,我們就可以嘗試自定義一個Java工具類,為Java的Native函數(shù)生成簽名字符串了,具體代碼如下:

    

/*
 *  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類提供一個支持變參的函數(shù)getSignature來獲取一個Java函數(shù)的簽名字符串,第一個參數(shù)為函數(shù)返回值類型的class對象,變參為每一個函數(shù)參數(shù)類型的class對象。


    具體用法示例如下,打印出不同類型的函數(shù)的簽名字符串。


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));


    輸出結(jié)果截屏如下:

    Android開發(fā)實踐:JNI函數(shù)簽名生成器

    

    關(guān)于JNI函數(shù)簽名生成器就介紹到這兒了,原理并不復(fù)雜所以我也沒有進行過多的分析,希望這個工具類能夠在大家今后的項目中派上用場,有任何疑問歡迎留言或者來信lujun.hust@gmail.com交流,或者關(guān)注我的新浪微博 @盧_俊 獲取最新的文章和資訊。



附件:http://down.51cto.com/data/2365199
向AI問一下細節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進行舉報,并提供相關(guān)證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI