Search code examples
javaandroidcandroid-ndkjava-native-interface

Calling a C method with double pointer parameter from Android with NDK/JNI


I am working with an API to control a finger print scanner attached to an android device. The native method I need to call requires a mixture of pointers and double pointers be handed to the method, but I am unsure how to do this.

The original C method has the definition:

BioErrType BioGetTemplates(BioHandle handle, char **badgeNumberList,uint8_t *templateIndexList, BioTemplate **bioTemplateList)

The provided Java method provided to call this is:

public native int BioGetTemplates(int handle, int [] badgeNumberList, byte [] templateIndexList, byte [][]bioTemplateList);

The documentation for the original C method states:

***    Gets from the biometric device a template for each of the listed
***  badge numbers.
***  
***    The badgeNumberList pointer is a pointer to a null terminated array
***  of pointers to badge number strings.  The bioTemplateList should be an
***  array of pointers to memory where templates can be stored, one pointer
***  for each possible template returned.
***    The templateIndexList is a pointer to an array of template indices.
***  If templateIndexList is not null, than its size must be the same as the
***  number of badge number strings provided via badgeNumberList, which must
***  be the same size as the array of template pointers provided via
***  bioTemplateList. If templateIndexList is null, than the bioTemplateList
***  array size must be a device specific multiple of the number of badge
***  numbers.  For all current devices, this multiple is 2, corresponding to
***  a primary and secondary template for each badge number.
***    Each template is copied from the device to the memory at the
***  corresponding pointer in the bioTemplateList. If no template for a
***  given badge number and template index is stored in the device, the
***  corresponding pointer in the bioTemplateList is set to NULL.  If a
***  template pointer in bioTemplateList is NULL and yet a template exists
***  for the corresponding badge number and index, BIOAPI_INVALID is returned.
***    The applications program shall provide a separate buffer, of a size
***  specific to the device type, for every template it expects.
***
***  returns:
***    BIOAPI_OK if all templates found were copied to the provided template
***  buffers.
***    BIOAPI_INVALID if the handle is invalid or the badgeNumberList pointer
***  is null or if the bioTemplateList pointer is null, or if any badge
***  number in the list is invalid, or if any template index is out of range
***  for the device, or if a null template pointer is provided for a
***  template that is requested and is in the device, or if the device could
***  not successfully be talked to.  This error code can be returned even if
***  some of the templates were copied from the device, if the function was
***  not able to complete.
***    BIOAPI_BUSY if another thread is currently using the library.

My current attempt to call the code:

            int[] badgeNumberList = { 100, 0 };
            byte[] templateIndexList = new byte[2 * (badgeNumberList.length - 1)];
            byte[][] bioTemplateList = new byte[1][2];

            try {
                mBio.bioGetTemplates(badgeNumberList, templateIndexList,
                        bioTemplateList);

                byte[] byteArr = bioTemplateList[0];
                BigInteger bigTemplate = new BigInteger(byteArr);

                Log.d(TAG, CLASS + "." + METHOD + " BigInt is: "
                        + bigTemplate.toString());

            } catch (BioError e) {
                Log.w(TAG, CLASS + "." + METHOD + ": " + e.getMessage());

            }

Note that the mBio object is a façade to the supplied Java API that deals with passing in handle and throws errors based on the integer return of the method.

I realise that I am not doing the correct thing with the output but as of yet I just want to see some output then I can deal with it later.

Currently running this code throws a BIOAPI_INVALID error.

I currently cannot debug on the device itself, only write to the log.

Thanks for any help you can give.


Solution

  • I spoke to those who wrote the API, the correct calling is:

    int[] badgeNumberList = new int[] { 100, 200 };
    byte[] templateIndexList = new byte[] { 0, 0 };
    byte[][] bioTemplateList = new byte[2][TEMPLATE_SIZE];
    
    mBio.getTemplates(badgeNumberList, templateIndexList, bioTemplateList);