Lo que ha hecho aquí con array_functions
es correcto y utilizable, pero se centra en envolver directamente el código de C++ y no utilizará una matriz de Java subyacente. Se puede utilizar con algo como:
SWIGTYPE_p_long_long array = MyLib.new_long_long_array(100); // new array with 100 elements.
for (int i = 0; i < 100; ++i) {
long_long_array_setitem(array, i, i);
}
new Test().SelectValues(array);
donde la matriz es sólo un proxy para un "verdadero" C++ trozo de memoria que se puede leer/escribir desde el lado de Java y pasar a las funciones envueltos.
Supongo por su pregunta que está interesado en hacer que esto se sienta más "natural" en el lado de Java. SWIG también proporciona array_class
que envuelve una matriz de manera similar, pero como un objeto propio en lugar de una colección de funciones estáticas. Por ejemplo si ha cambiado el archivo de interfaz para utilizar array_class(long long, LongLongArray)
en lugar de array_functions
que puede hacer:
LongLongArray array = new LongLongArray(100);
for (int i = 0; i < 100; ++i) {
array.setitem(i,i);
}
new Test().SelectValues(array.cast());
Usted puede hacer realmente TRAGO hacer más que eso con algunas typemaps si quieres. Tu clase de ejemplo no tiene una longitud en SelectValues
, así que supongo que estás terminando la matriz 0 aunque también puedes pasar la longitud con unos pocos cambios simples.
(Por conveniencia %inline
D Sus clase para reducir el número de archivos y ha añadido una aplicación simulada de la misma para la prueba)
%module MyLib
%{
#include <iostream>
%}
%typemap(jtype) long long values[] "long[]"
%typemap(jstype) long long values[] "long[]"
%typemap(javain) long long values[] "$javainput"
%typemap(jni) long long values[] "jlongArray"
%typemap(in) long long values[] {
jboolean isCopy;
$1 = JCALL2(GetLongArrayElements, jenv, $input, &isCopy);
}
%inline %{
class Test
{
public:
void SelectValues(long long values[]) {
while (*values) {
std::cout << *values++ << "\n";
}
}
};
%}
Aquí hemos dicho que tanto el TRAGO clase proxy genera y la clase JNI se genera va a funcionar con long[]
, es decir, una matriz de Java. No necesitamos hacer nada en la conversión JNI de Java Proxy a Java, por lo que el mapa de tipos javain
es solo un paso directo. En el lado C++ del JNI que es un jlongArray
, que también especificamos en otro mapa de tipos.
entonces necesitamos un typemap in
para organizar la conversión de jlongArray a long long[]
en el lado de la C++ - no hay una sola llamada JNI para eso y no nos importa si se trata de una copia o la memoria real de la JVM que terminamos utilizando.(Es posible que cuidar si desea modificar los resultados y hacerla visible de nuevo dentro de Java por ejemplo)
He probado esto con:
public class run {
public static void main(String[] argv) {
System.loadLibrary("mylib");
long arr[] = {100,99,1,0}; // Terminate with 0!
new Test().SelectValues(arr);
}
}
¿Qué hizo exactamente lo que usted esperaría.
el 'jlong' que viste en el lado JNI es cómo SWIG envuelve todo lo que no es un tipo primitivo. – Flexo