2009-09-16 7 views
7

Je ne connais pas très bien C, mais j'ai besoin d'utiliser une bibliothèque C dans mon code java. J'ai créé la DLL et suis capable d'y accéder très bien, mais j'essaye de retourner un tableau d'ints du code C au code java. En C je pensais que vous pouviez simplement renvoyer un pointeur vers le tableau, mais cela ne fonctionne pas comme prévu dans mon code Java. Voici le code C:Renvoyer un tableau C vers Java en utilisant JNA

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 je teste cela en C++ en faisant

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

il fonctionne très bien et je reçois les valeurs 739, 255 comme prévu.

J'essaie de l'utiliser en Java avec le paquet JNA comme si (mais cela me donne 739, -16.777.214):

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

Dans la documentation de la JNA, il dit des tableaux primitifs tels que int *buf seraient mis en correspondance avec int[] buf en Java, mais quand j'essaye de changer le type de retour de IntByReference à int[] alors j'obtiens une exception illegalArgumentException.

Je ne sais pas si je retourne correctement le tableau de C ou si je n'y accède pas correctement en Java. Toute aide serait appréciée.

Répondre

4

Je préférerais changer la fonction C si je peux pour:

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

6

Le code est bon devrait être mieux (voir d'autres commentaires), cependant, le problème principal est que j'utilisais mal la méthode java getInt() pour le pointeur. Il semble que j'aurais dû utiliser le getIntArray().

3

Plus et peut-être plus explication claire est que vous prototyper votre fonction Java pour recevoir pointeur (ou un successeur de pointeur) -

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

Lors de la création de la fonction de rappel lui-même, vous utilisez getByteArray (int), ou l'un des autres getArrays. Je ne voudrais pas utiliser une telle fonction, car le tableau retourné ne sera jamais libéré/supprimé.

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