使用JNA将C数组返回给Java

rav*_*vun 7 java arrays jna

我对C不太熟悉,但我需要在我的java代码中使用C库.我已经创建了DLL并且能够很好地访问它,但我试图从C代码返回一个int数组到java代码.

在CI中,您可以简单地返回一个指向数组的指针,但它的工作方式与我在Java代码中的预期不同.这是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;
}
Run Code Online (Sandbox Code Playgroud)

如果我用C++在C++中测试它

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

然后它工作正常,我得到的值739,255像预期的那样.

我尝试在Java中使用它与JNA包这样(但这给了我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));
    }
}
Run Code Online (Sandbox Code Playgroud)

在JNA文档,它说基本数组如int *buf将被映射到int[] bufJava中,但是当我尝试更改返回类型IntByReferenceint[]然后我得到一个IllegalArgumentException.

我不知道我是否正确地从C返回数组,或者我是不是在Java中正确访问它.任何帮助,将不胜感激.

rav*_*vun 6

C代码是罚款应该会更好(见其他意见),然而,主要的问题是,我被滥用的Java getInt()为指针的方法.看来我应该一直在使用getIntArray().


Ust*_*gat 4

我不会使用这样的函数,因为返回的数组永远不会被释放/删除。如果可以的话,我宁愿更改 C 函数:

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