Java中的Java jbytearray访问(JNI)

时间:2013-08-12 18:44:11

标签: java visual-c++ java-native-interface jnienv

我是一个java新手,所以请光临我。

我有一组在我的工作中需要用C / C ++运行的java类。

而且,因为我对java很新,所以我一步一步。我已经能够用string,int double等调用java了,但最终结果将得到一个字节数组(pdf文档)所以我试着发回一个简单的两个元素字节数组。

这是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.

任何帮助都将不胜感激。

2 个答案:

答案 0 :(得分:2)

尝试将字段Byte[] data = new Byte[2];更改为byte[] data = new byte[2];

然后在您的JNI方法中使用GetFieldID(clsReturn, "data", "[B"));

修改:为了能够获得每种类型的内部签名(在您的案例中[Bbyte[]),您可以声明您想要的类字段(我们称之为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
}

答案 1 :(得分:1)

对于FieldID,我认为你想使用"[B"代替"Ljava/lang/ByteArray;",而实际上并不是一个类。

修改:由于您使用的是我在原始回复中遗漏的Byte课程,请使用“[Ljava/lang/Byte;"