2009-09-16 11 views
7

No estoy muy familiarizado con C, pero necesito usar una biblioteca C en mi código de Java. He creado la DLL y puedo acceder a ella muy bien, pero estoy intentando devolver una matriz de entradas del código C al código de Java.Devolver matriz C a Java utilizando JNA

En C pensé que simplemente podría devolver un puntero a la matriz, pero no está funcionando como esperaba en mi código de Java. Aquí está el código C:

int * getConusXY(double latitude, double longitude) { 
    maparam stcprm; 
    double reflat = 25, reflon = -95, 
      lat1 = 20.191999, lon1 = -121.54001, 
      x1 = 0, y1 = 0, x2 = 1073, y2 = 689, 
      gsize = 5.079, scaLat = 25, scaLon = -95, orient = 0; 
    double x, y; 
    int* xy; 

    xy = malloc(2 * sizeof *xy); 

    stlmbr(&stcprm, reflat, reflon); 
    stcm1p(&stcprm, x1, y1, lat1, lon1, scaLat, scaLon, gsize, orient); 
    cll2xy(&stcprm, latitude, longitude, &x, &y); 

    xy[0] = (int) x; 
    xy[1] = (int) y; 

    return xy; 
} 

Si puedo probar esto en C++ haciendo

int* xy = getConusXY(33.92, -84.33); 
cout << xy[0] << " " << xy[1] << endl; 

entonces funciona bien y me da los valores de 739, 255 como se esperaba.

trato de usarlo en Java con el paquete JNA como tal (pero esto me da 739, -16777214):

public class DmapFDllLibrary { 
    interface DmapFLibrary extends Library { 
     DmapFLibrary INSTANCE = (DmapFLibrary) Native.loadLibrary("DmapFDll", 
       DmapFLibrary.class); 

     IntByReference getConusXY(double latitude, double longitude); 
    } 

    public static void main(String... strings) { 
     IntByReference xy_ref = DmapFLibrary.INSTANCE.getConusXY(33.92, -84.33); 
     Pointer p = xy_ref.getPointer(); 
     System.out.println(p.getInt(0) + " " + p.getInt(1)); 
    } 
} 

En la documentación JNA que dice matrices primitivas como int *buf se asignan a int[] buf en Java, pero cuando trato de cambiar el tipo de devolución de IntByReference a int[], entonces obtengo una excepción de objeto ilegal.

No sé si devuelvo la matriz correctamente desde C o si simplemente no estoy accediendo correctamente a ella en Java. Cualquier ayuda sería apreciada.

Respuesta

4

No utilizaría esa función, porque nunca será liberado de la matriz devuelta/borrado. yo preferiría cambiar la función C si lo que pueda para:

void myFunc(Pointer resuls, int numBytes, byte const * returnArray)

6

El código C está bien debería ser mejor (ver otros comentarios), sin embargo, el problema principal es que estaba haciendo un uso incorrecto del método java getInt() para el puntero. Parece que debería haber estado usando el getIntArray().

3

La explicación más larga y tal vez más claro es que un prototipo de su función de Java para recibir puntero (o un sucesor del puntero) -

byte[] myFunc(Pointer result, int numBytes); 

Al crear la devolución de llamada en sí, se utiliza getByteArray (int), o uno de los otros getArrays.

byte[] myFunc(Pointer resuls, int numBytes) 
{ 
    return Pointer.getByteArray(numBytes); 
} 
Cuestiones relacionadas