我读过很多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之外的所有东西。它模拟计算返回的数据。
非常感谢任何提示。
答案 0 :(得分:2)
谢谢@cubrr。 这是结尾。只需致电
buf.order(ByteOrder.LITTLE_ENDIAN)
在读取和编写Java中的值之前。 我猜对了,但我没有发现它,所以我猜它是根据操作系统自动设置的。事实并非如此。