1

仕事で C/C++ で実行する必要がある一連の Java クラスがあります。

そして、私はJavaにかなり慣れていないので、一度に一歩ずつ進めています。string、int double などで Java を呼び出せるようになりましたが、最終結果はバイト配列 (pdf ドキュメント) を取得することになるので、単純な 2 要素のバイト配列を送信してみました。

ここにJavaがあります:

public class ReturnData
{
    int returnValue;
    String Log;
    Byte[] data = new Byte[2];

     public ReturnData(int nRetVal, String szLog)
     {
         this.data[0] = 100;
         this.data[1] = 12;
         this.returnValue = nRetVal;
         this.Log = szLog;
     }
}

そして、これがc ++コードです(JNIの初期化が削除されました。単純な型で機能するため...)

jbyteArray jbyteData = (jbyteArray)jniEnvironment->GetObjectField(jobjRetData,
    jniEnvironment->GetFieldID(clsReturn, "data", "Ljava/lang/ByteArray;"));

そして今、次のような jbyteData 要素にいつでもアクセスできます。

jsize len = jniEnvironment->GetArrayLength(jbyteData);

例外が発生します

System.AccessViolationException was unhandled
Message: Attempted to read or write protected memory. This is often an indication that other 
memory is corrupt.
4

2 に答える 2

2

FieldID については、実際にはクラスではない"[B"の代わりに使用したいと思います。"Ljava/lang/ByteArray;"

編集:Byte元の応答で見逃したクラスを使用しているため、[Ljava/lang/Byte;"代わりに「」を使用してください

于 2013-08-12T18:52:01.207 に答える
2

Byte[] data = new Byte[2];フィールドを次のように変更してみてくださいbyte[] data = new byte[2];

次に、JNIメソッドで使用しますGetFieldID(clsReturn, "data", "[B"));

編集:各タイプの内部署名を取得できるようにするには([Bあなたbyte[]のケースでは)、必要なフィールドをクラスに宣言し(それを呼び出しましょうTest)、コンパイルしてから実行しますjavap -s Test。以下のような出力が生成されます。

Compiled from "SimpleMain.java"
public class SimpleMain extends java.lang.Object{
public byte[] data;
  Signature: [B            // <-- signature shows the internal type 
public SimpleMain();
  Signature: ()V
public static void main(java.lang.String[]);
  Signature: ([Ljava/lang/String;)V
}
于 2013-08-12T19:00:04.140 に答える