1

私はJavaとJNAの初心者です。JNA を使用して、Java からネイティブ DLL 関数をロードして使用しています。

ポインターを配列に渡す際に問題に直面しています。仕様に従って、Java からこの配列にデータを入力し、この配列へのポインターを DLL に送信しようとしています。

これは、ネイティブ コールの外観です。

StartCom(UNUM8 *pCoPData)
From the spec: pCoPData -> Reference of the buffer holding the data

対応する JNA マッピング、

    int[] buf = new int[2];
    buf[0] = 0x1A;
    buf[1] = 0x10;

    Pointer pCoPData = new Memory(8);
    pCoPData.write(0, buf, 0, buf.length);

            Library.INSTANCE.StartCom(pCoPData);

上記のコードを実行すると、配列 0x1A の最初の要素のみが使用され、2 番目のバイトが無視されることが dll ログからわかります。DLL は、常に配列の最初の要素のみを認識します。

この問題が発生する可能性は 2 つしかないと考えています。

  1. The above approach I have taken to populate and send the address of a Java array  to the DLL is incorrect.
  2. The DLL is expecting a UNUM8* whereas I am sending a UNUM32*. I will try with byte[] instead of int[] and see if there is any difference.

どんな提案も大いに役立ちますか? 私にお知らせください。よろしくお願いします!

4

1 に答える 1

1

入力時に関数に不適切な型を渡すと、適切な結果が期待できるのはなぜですか?

関数が 1 つまたは複数の 8 ビット要素 ( byteJava では、おそらくUNUM8ネイティブ コードでは 8 ビット) へのポインターを予期している場合、1 つまたは複数の 8 ビット要素へのポインターに相当するものを渡す必要があります。2 つの 32 ビット要素で初期化したメモリへのポインタを渡しています。8 ビットと 32 ビットの場合のメモリは次のようになります (すべての値は 8 ビット バイトを表します)。

2 つの 8 ビット値をメモリに書き込んだ後:

base+0x0: 0x1A
base+0x1: 0x10

2 つの 32 ビット値をメモリに書き込んだ後:

base+0x0: 0x1A 0x00 0x00 0x00
base+0x4: 0x10 0x00 0x00 0x00

したがって、ネイティブ コードが から読み取りを開始した場合base、メモリの初期化方法によって値が大きく異なることがわかります。

ところで、関数呼び出し自体よりも長く渡したメモリへの参照をネイティブ コードが保持する必要がない場合は、 を割り当てて初期化するのではなく、単にパラメータbyte[]として使用できます。UNUM8*Memory

于 2012-10-13T15:14:36.147 に答える