NewDirectByteBuffer返回奇怪的值

时间:2018-01-12 16:58:08

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

我读过很多SO Q / A,但我真的无法解决这个问题。 我需要在JNI项目中使用C ++中的向量(库需要它)。 所以我调用一个C ++方法初始化向量并返回一个指向底层数组的指针。 Java应该填充它,然后调用另一个C ++方法来进行详细说明。 目前,要调试代码,doComputetion需要一个ByteBuffer,但它不会再用了。

代码如下:

的.cpp:

using namespace std;

JNIEXPORT jobject JNICALL Java_nnJNI_allocateStorage(JNIEnv * env, jobject obj, jint num)
{
vector<jfloat>* in = new vector<jfloat>(num, 40.0);
jobject jbuffer = env->NewDirectByteBuffer(in->data(), in->size() * sizeof(jfloat));
return env->NewGlobalRef(jbuffer); //I know this can be avoided
}

JNIEXPORT jobject JNICALL Java_nnJNI_doComputation(JNIEnv * env, jobject, jobject in)
{
float* f = (float*)env->GetDirectBufferAddress(in);
float* out = new float[1];
out[0] = 10;
jobject jbuffer = env->NewDirectByteBuffer(out, 1 * sizeof(jfloat));
return jbuffer;
}

java class:

public class nnJNI {
static {
    System.loadLibrary("YIAnnLib");
}

private native ByteBuffer allocateStorage(int size);

private native ByteBuffer doComputation(ByteBuffer buffer);

public void demo() {
    ByteBuffer buf = allocateStorage(2);
    float f = buf.getFloat();
    ByteBuffer b = ByteBuffer.allocateDirect(8);
    b.putFloat(10); b.putFloat(12);
    ByteBuffer res = doComputation(b);
    float g = res.getFloat();
}
}

如您所见,我使用值40.0初始化数组。在Java中,float f是除了40.0之外的所有内容。我真的无法理解错误:没有人会释放用new声明的向量。它应该留在那里。我注意到一个奇怪的事情:在C ++中分配时,如果我将堆栈上的向量声明为静态,它似乎起作用。很明显,我不会做这么糟糕的事情。

另外相反的做法不起作用:C ++中的doComputation中的float * f是除了10之外的所有值(它应该具有在Java中初始化的值)。

在Java中浮动g就是除了10之外的所有东西。它模拟计算返回的数据。

非常感谢任何提示。

1 个答案:

答案 0 :(得分:2)

谢谢@cubrr。 这是结尾。只需致电

 buf.order(ByteOrder.LITTLE_ENDIAN) 

在读取和编写Java中的值之前。 我猜对了,但我没有发现它,所以我猜它是根据操作系统自动设置的。事实并非如此。