使用JNA将C数组返回给Java

7

我不太熟悉C语言,但我需要在我的Java代码中使用一个C库。我已经创建了DLL并能够正常访问它,但我试图从C代码返回一个整数数组到Java代码。

在C语言中,我认为你可以简单地返回指向数组的指针,但在我的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;
}

如果我用C++测试这个,可以这样做:

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

如果这样做,它可以正常工作,并且我得到了期望的值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));
    }
}

在JNA文档中,它说像int *buf这样的原始数组将被映射到Java中的int[] buf,但是当我尝试将返回类型从IntByReference更改为int[]时,我会收到一个IllegalArgumentException异常。
我不知道我是否正确地从C中返回了数组,或者我在Java中没有正确地访问它。任何帮助都将不胜感激。
3个回答

6

这段 C 代码 没问题 应该改进(见其他评论),但主要问题是我错误地在指针上使用了 java 的 getInt() 方法。看起来我应该使用 getIntArray() 方法。


4
更长、更清晰的解释是,您原型化Java函数以接收Pointer(或Pointer的后继)-
byte[] myFunc(Pointer result, int numBytes);

在创建回调本身时,您可以使用 getByteArray(int) 或其他 getArrays 之一。
byte[] myFunc(Pointer resuls, int numBytes)
{
     return Pointer.getByteArray(numBytes);
}

4

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

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


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接