使用 JNA 将 C 数组返回到 Java

发布于 2024-08-05 11:09:46 字数 1773 浏览 2 评论 0原文

我对 C 不太熟悉,但我需要在我的 java 代码中使用 C 库。我已经创建了 DLL 并且能够很好地访问它,但我试图将一个整数数组从 C 代码返回到 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;
}

如果我在 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 之类的原始数组将映射到 int[] buf 在 Java 中,但是当我尝试将返回类型从 IntByReference 更改为 int[] 时,我得到了非法参数异常。

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

I am not too familiar with C, but I need to use a C library in my java code. I have created the DLL and am able to access it just fine, but I am attempting to return an array of ints from the C code to the java code.

In C I thought you could simply return a pointer to the array, but it's not working like I expect in my Java code. Here's the C code:

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

If I test this in C++ by doing

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

then it works fine and I get the values 739, 255 like expected.

I try using it in Java with the JNA package like so (but this gives me 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));
    }
}

In the JNA documentation it says primitive arrays such as int *buf would be mapped to int[] buf in Java, but when I try changing the return type from IntByReference to int[] then I get an illegalArgumentException.

I don't know if I'm returning the array correctly from C or if I'm just not accessing it correctly in Java. Any help would be appreciated.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

故乡的云 2024-08-12 11:09:46

C 代码很好应该更好(请参阅其他评论),但是,主要问题是我误用了 java getInt() 指针方法。看来我应该使用getIntArray()

The C code is fine should be better (see other comments), however, the main issue is that I was misusing the java getInt() method for the pointer. It seems I should've been using the getIntArray().

岁月苍老的讽刺 2024-08-12 11:09:46

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

void myFunc(指针结果,int numBytes,byte const * returnArray)

I would not use such a function, because the returned array will never be freed/deleted.
I would rather change the C function if I can to:

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

触ぅ动初心 2024-08-12 11:09:46

更长且可能更清晰的解释是,您将 Java 函数原型化以接收 Pointer(或 Pointer 的后继) -

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

创建回调本身时,您使用 getByteArray(int) 或其他 getArray 之一。

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

The longer and perhaps more clear explanation is that you prototype your Java function to receive Pointer (or a successor of Pointer) -

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

When creating the callback itself, you use getByteArray(int), or one of the other getArrays.

byte[] myFunc(Pointer resuls, int numBytes)
{
     return Pointer.getByteArray(numBytes);
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文