How to define swig typemap for returning unsigned char* back to java

前端 未结 1 1383
眼角桃花
眼角桃花 2021-01-06 23:18

I have a Java Application that calls a c library for performing crypto functions. This is a custom library implemented in c that we need to use from some Java programs. I ne

1条回答
  •  清酒与你
    2021-01-07 00:04

    The easiest way to do work with byte arrays in Java is to use %array_class (or %array_functions) which is like %pointer_functions but for an entire array, not just a single element. I put together a complete example for you, using this header file as a test:

    inline void foo(unsigned char *bytearr) {
      bytearr[0] = 1;
      bytearr[1] = 2;
      bytearr[2] = 3;
      bytearr[3] = 100;
    }
    

    We can wrap this with SWIG with:

    %module test
    
    %{
    #include "test.h"
    %}
    
    %include 
    %array_class(unsigned char,ByteArr);
    
    %include "test.h"
    
    // Emit Java code to automatically load the shared library
    %pragma(java) jniclasscode=%{
      static {
        try {
            System.loadLibrary("test");
        } catch (UnsatisfiedLinkError e) {
          System.err.println("Native code library failed to load. \n" + e);
          System.exit(1);
        }
      }
    %}
    

    I also put together some Java to exercise this function:

    public class run {
      public static void main(String[] argv) {
        ByteArr arr = new ByteArr(4); // Initial size 4
        // You could set some values before passing in if you wanted to.
        test.foo(arr.cast());
        System.out.println(arr.getitem(0) + ", " + arr.getitem(1) + ", " + arr.getitem(2) + ", " + arr.getitem(3));
      }
    }
    

    which compiled and ran. Note that unsigned char in C or C++ is represented in Java as short - Java doesn't have any unsigned types, so the smallest type which fits the range 0-255 is a short. byte doesn't cover it by default. (You could play games re-mapping unsigned char to byte in other ways but that's far from intuitive so the default is not to).

    You can do more advanced things if you want. For example if you know the size of the array you can use arrays_java.i. This example creates typemaps using JNI for returning an array of unsigned char. This example shows how to pass an array in to a function using JNI typemaps. (It's using long instead of byte, but the it's literally a search and replace to change that).

    0 讨论(0)
提交回复
热议问题