java jni bytearray swig unsigned-char

Cómo definir swig typemap para devolver char sin signo*a java



jni bytearray (1)

La forma más fácil de trabajar con matrices de bytes en Java es usar %array_class (o %array_functions ) que es como %pointer_functions pero para una matriz completa, no solo un elemento. Puse un ejemplo completo para ti, usando este archivo de cabecera como prueba:

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

Podemos envolver esto con SWIG con:

%module test %{ #include "test.h" %} %include <carrays.i> %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); } } %}

También armé algo de Java para ejercer esta función:

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

que compiló y ejecutó. Tenga en cuenta que la unsigned char en C o C ++ se representa en Java como short : Java no tiene ningún tipo sin signo, por lo que el tipo más pequeño que se ajusta al rango 0-255 es corto. byte no lo cubre por defecto. (Podría jugar juegos reasignando unsigned char a byte de otras formas, pero eso está lejos de ser intuitivo, por lo que el valor predeterminado no es).

Puede hacer cosas más avanzadas si lo desea. Por ejemplo, si conoce el tamaño de la matriz, puede usar arrays_java.i . Este ejemplo crea mapas de tipos utilizando JNI para devolver una matriz de caracteres unsigned char . Este ejemplo muestra cómo pasar una matriz a una función usando JNI typemaps. (Está usando long lugar de byte , pero literalmente es una búsqueda y reemplazo para cambiar eso).

Tengo una aplicación Java que llama a la biblioteca de CA para realizar funciones de cifrado. Esta es una biblioteca personalizada implementada en c que necesitamos usar de algunos programas Java. Necesito una forma de definir un mapa de tipos SWIG que me permita llamar a una función que pase bytearray desde Java y tratarla como un puntero de carácter sin signo en la función C donde la función c llena datos y los devuelve a Java

Extracto de mi actual archivo de interfaz infeliz es el siguiente

%module CryptoFacade %pointer_functions(int, intp); %pointer_functions(unsigned char, unsigned_charp); int enCrypt(char* clearText, int clearLen,unsigned char* retCipherText, int *retCipherLen);

Y extracto de mi código Java infeliz es el siguiente. En el siguiente código esperaba que la llamada a la función enCrypt me diera un buffer pero me da un "short" según el código generado. (Ver comentarios en el código)

class MainLoader { static { System.loadLibrary("dccasecuJ"); //Load my crypto library } public static void main(String[] args) { // Define the parameters to be passed by reference SWIGTYPE_p_int retCipherLen=CryptoFacade.new_intp(); SWIGTYPE_p_unsigned_char retCipherText = CryptoFacade.new_unsigned_charp(); CryptoFacade myFacade=new CryptoFacade(); // Call crypto library function. First two are value parameters, next two are return myFacade.enCrypt("STRING-TO-ENCRYPT", 17, retCipherText, retCipherLen); // The length I get back in fourth parameter is just fine int gotLen= CryptoFacade.intp_value(retCipherLen); //The value I get for the Ciphertext though is a "short" ... no good // I need a byte[] in java that has the ciphertext short gotText= CryptoFacade.unsigned_charp_value(retCipherText);

Creo que debería cambiar la definición de mi interfaz a algo más abajo donde hago que mi tercer parámetro sea un jbytearray y luego tengo que implementar un mapa de tipos que copiará los contenidos apuntados por el puntero de un carácter sin signo en el programa C a un java bytearray.

Estoy perfectamente bien si tengo que especificar la longitud del contenido a 256 bytes, porque manejar longitudes arbitrarias puede ser complicado.

¿Alguien me puede indicar dónde puedo encontrar un mapa de tipos de este tipo (soy nuevo en SWIG y no tengo experiencia en escribir mapas de tipos)

%module CryptoFacade %pointer_functions(int, intp); %pointer_functions(unsigned char, unsigned_charp); int enCrypt(char* clearText, int clearLen, jbyteArray retCipherText, int *retCipherLen);