2009-09-16 29 views
7

Tôi không quá quen thuộc với C, nhưng tôi cần sử dụng thư viện C trong mã java của mình. Tôi đã tạo ra các DLL và am có thể truy cập nó chỉ là tốt, nhưng tôi đang cố gắng trả lại một mảng ints từ mã C để mã java.Trả về mảng C thành Java bằng cách sử dụng JNA

Trong C Tôi nghĩ bạn có thể đơn giản trả về một con trỏ tới mảng, nhưng nó không hoạt động như tôi mong đợi trong mã Java của tôi. Dưới đây là đoạn code 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; 
} 

Nếu tôi thử nghiệm này trong C++ bằng cách làm

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

sau đó nó hoạt động tốt và tôi nhận được các giá trị 739, 255 như mong đợi.

tôi cố gắng sử dụng nó trong Java với gói JNA như vậy (nhưng điều này mang lại cho tôi 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)); 
    } 
} 

Trong tài liệu JNA nó nói mảng nguyên thủy như int *buf sẽ được ánh xạ tới int[] buf trong Java, nhưng khi tôi thử thay đổi kiểu trả về từ IntByReference thành int[] thì tôi nhận được một exceptionArgumentException.

Tôi không biết liệu tôi có trả về đúng mảng từ C hay không nếu tôi không truy cập chính xác trong Java. Bất kỳ trợ giúp sẽ được đánh giá cao.

Trả lời

4

Tôi sẽ không sử dụng chức năng như vậy, vì mảng được trả về sẽ không bao giờ được giải phóng/xóa. Tôi thà thay đổi chức năng C nếu tôi có thể đến:

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

6

Mã C là tốt hơn nên tốt hơn (xem các nhận xét khác), tuy nhiên, vấn đề chính là tôi đã lạm dụng phương thức java getInt() cho con trỏ. Có vẻ như tôi nên sử dụng getIntArray().

3

Lời giải thích lâu hơn và có lẽ rõ ràng hơn là bạn tạo thử nghiệm chức năng Java của bạn để nhận con trỏ (hoặc một người kế nhiệm của con trỏ) -

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

Khi tạo callback chính nó, bạn sử dụng getByteArray (int), hoặc một trong những getArrays khác.

byte[] myFunc(Pointer resuls, int numBytes) 
{ 
    return Pointer.getByteArray(numBytes); 
} 
Các vấn đề liên quan