7

私は 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 のドキュメントでは、Java でint *bufマップされるようなプリミティブ配列と書かれていますが、戻り値の型を からに変更しようとすると、 illegalArgumentException が発生します。int[] bufIntByReferenceint[]

C から配列を正しく返しているのか、それとも Java で配列に正しくアクセスしていないのかわかりません。どんな助けでも大歓迎です。

4

3 に答える 3

6

C コードの方が優れているはずですが (他のコメントを参照)、主な問題はgetInt()、ポインターの Java メソッドを誤用していたことです。を使うべきだったようですgetIntArray()

于 2009-09-16T14:41:20.930 に答える
4

より長く、おそらくより明確な説明は、ポインター (またはポインターの後継) を受け取るように Java 関数のプロトタイプを作成することです。

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

コールバック自体を作成するときは、getByteArray(int) または他の getArray のいずれかを使用します。

byte[] myFunc(Pointer resuls, int numBytes)
{
     return Pointer.getByteArray(numBytes);
}
于 2010-10-28T15:10:41.203 に答える
4

返された配列が解放/削除されることはないため、このような関数は使用しません。できれば、C 関数を変更したいと思います。

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

于 2011-11-02T17:30:15.507 に答える