我通过JNI访问MappedByteBuffers有一个奇怪的问题。我的目标是使用C库来操作一些数据。
我首先使用像这样的
的Java代码加载一个浮动缓冲区private ByteBuffer vertices;
private void load(){
FileInputStream inputStream = new FileInputStream(filepath);
FileChannel channel = inputStream.getChannel();
vertices = channel.map(FileChannel.MapMode.READ_ONLY, 0,
NUM_VERTICES * 3 * 4); //3 floats xyz
inputStream.close();
channel.close();
}
然后我通过GetDirectBufferAddress()这样使用JNI访问它(我正在减少所有JNI的东西)
include <"my_external_header.h">
extern "C" JNIEXPORT jint JNICALL
Java_com_my_package_MyJavaClass_myMethod(JNIEnv* env, jobject obj){
(..) //JNI get Field ids and stuff
float(*)[3] vertices = reinterpret_cast<float(*)[3]>(env->GetDirectBufferAddress(j_vertices));
// All the data is awesome, can iterate through all the vertices, lets call our external function
myExternalFunction(vertices);
}
在GetDirectBufferAddress()调用之后一切运行良好,我可以迭代遍历数组中的所有数据,没有任何问题,所有数据都是正确的。然后我将它传递给驻留在不同.so文件中的外部api函数。
extern "C" void myExternalFunction(float(*)[3] vertices){
float x = vertices[0][0]; //This immediately causes a SIGBUS
}
我能够通过将MappedByteBuffer(在I / 0读取操作之后)转换为allocateDirect()ByteBuffer来解决这个问题,但它强迫我使用不必要的副本,是否有人有任何线索或指向要阅读的内容? Mmapped文件似乎有一些我无法理解的陷阱。