2009-09-16 11 views
7

Nie jestem zbyt zaznajomiony z C, ale muszę użyć biblioteki C w moim kodzie java. Stworzyłem DLL i mam dostęp do niego po prostu dobrze, ale próbuję zwrócić tablicę ints z kodu C do kodu java.Powracanie tablicy C do Javy przy użyciu JNA

W C Pomyślałem, że możesz po prostu zwrócić wskaźnik do tablicy, ale to nie działa tak, jak oczekuję w moim kodzie Java. Oto kod 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; 
} 

Gdybym to sprawdzić w C++, wykonując

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

to działa dobrze i uzyskać wartości 739, 255 jak można oczekiwać.

próbuję go używać w języku Java z pakietu JNA jak tak (ale to daje mi 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)); 
    } 
} 

W dokumentacji JNA to mówi prymitywne tablice takie jak int *buf będą odwzorowywane na int[] buf w Javie, ale kiedy próbuję zmienić typ zwracania z IntByReference na int[], otrzymuję wyjątek illegalArgumentException.

Nie wiem, czy zwracam tablicę poprawnie z C lub jeśli po prostu nie mam dostępu do niej poprawnie w Javie. Każda pomoc będzie doceniona.

Odpowiedz

4

Nie używałbym takiej funkcji, ponieważ zwrócona tablica nigdy nie zostanie zwolniona/usunięta. wolałbym zmienić funkcję C, jeśli mogę się:

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

6

kod C jest w porządku powinny być lepsze (patrz inne uwagi), ale głównym problemem jest to, że został niewłaściwie metodę java getInt() dla wskaźnika. Wygląda na to, że powinienem był używać getIntArray().

3

Im dłużej i być może bardziej jasne wyjaśnienie jest takie, że prototyp swoją funkcję Java, aby otrzymać wskaźnik (lub następcy Pointer) -

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

Podczas tworzenia samego zwrotnego, należy użyć getByteArray (int), lub jeden z innych getArrays.

byte[] myFunc(Pointer resuls, int numBytes) 
{ 
    return Pointer.getByteArray(numBytes); 
} 
Powiązane problemy