通过JNI传递int16_t和uint8_t值的问题

时间:2017-06-08 02:39:55

标签: java android c++ casting java-native-interface

我在C ++中有一个结构如下:

typedef struct {
  int16_t param1;
  uint8_t param2;
  uint8_t param3;
} Sample;

我在JNI中收到vector<Sample>,我想将其传递给Java层。

我的java类是:

public class JavaSample {
    short mP1;
    short mP2;
    short mP3;

    public JavaSample(short p1, short p2, short p3) {
      mP1 = p1; mP2 = p2; mP3 = p3;
    }
}

在Java中我有方法:

 public ArrayList<Sample> getList() { return new ArrayList<>();}
 public void addSample(ArrayList<Sample> list, short p1, short p2, short p3) 
 { list.add(new Sample(p1, p2, p3));
 }

在JNI中,我首先使用getList得到一个空的arraylist。接下来,我遍历vector<Sample>并为我做的每个样本

env->CallVoidMethod(clazzObj, methodId, list, sample.param1, sample.param2, sample.param3);

此处clazzObj指向我的java边课,methodId指向addSample方法,list是最初为空的列表。

使用上面的代码,当我运行程序时,它会崩溃并出现如下错误: JNI ERROR (app bug): expected jshort but got value of -15007284 as argument 3 to void com.example.MainActivity.addSample(java.util.ArrayList, short, short, short)

所以它似乎发现了垃圾值超过该字段的容量。这似乎随​​机发生在3个参数中的任何一个(即使int16_t理想情况下也应匹配短。) 如果我使用int而不是short,那么它不会崩溃,但垃圾值会传递到java端。 有谁能建议发生什么事?

1 个答案:

答案 0 :(得分:0)

在拨打电话时尝试使用显式转换:

env->CallVoidMethod(clazzObj, methodId, list, (jshort)sample.param1, (jshort)sample.param2, (jshort)sample.param3);

问题是 CallVoidMethod()没有关于其参数的预期长度的信息(超出 methodId ),并且使用 sample.param2 和 sample.param3 ,而Java方法知道这些应该是两个字节。因此,Java方法解释的最后一个参数是垃圾。