문제

C에 너무 익숙하지는 않지만 Java 코드에서 C 라이브러리를 사용해야합니다. DLL을 만들었고 잘 액세스 할 수 있지만 C 코드에서 Java 코드로의 INT 배열을 반환하려고합니다.

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를 얻습니다.

JNA 패키지와 함께 Java로 사용하려고합니다 (그러나 이것은 나에게 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에서 올바르게 액세스하지 않는지 모르겠습니다. 모든 도움이 감사하겠습니다.

도움이 되었습니까?

해결책

반환 된 배열은 절대로 해제/삭제되지 않기 때문에 그러한 함수를 사용하지 않을 것입니다. 할 수 있다면 C 함수를 변경하려고합니다.

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

다른 팁

C 코드 괜찮습니다 그러나 더 나아질 것입니다 (다른 의견 참조) 주요 문제는 내가 Java를 잘못 사용하고 있다는 것입니다. getInt() 포인터를위한 방법. 내가 사용 했어야했던 것 같다 getIntArray().

더 길고 아마도 더 명확한 설명은 Java 기능을 프로토 타입하여 포인터 (또는 포인터의 후계자)를 받는다는 것입니다.

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

콜백 자체를 만들 때 GetByTearRay (int) 또는 다른 GetArray 중 하나를 사용합니다.

byte[] myFunc(Pointer resuls, int numBytes)
{
     return Pointer.getByteArray(numBytes);
}
라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top