jbyte* 作为 JNI 中本机 C++ 方法的 ByteBuffer
Posted
技术标签:
【中文标题】jbyte* 作为 JNI 中本机 C++ 方法的 ByteBuffer【英文标题】:jbyte* as ByteBuffer from Native C++ method in JNI 【发布时间】:2012-07-13 21:26:36 【问题描述】:这里是原生 C++ 方法。
JNIEXPORT jboolean JNICALL Java_xpnp_XpNamedPipe_readBytes
(JNIEnv* pEnv, jclass cls, jlong pipeHandle, jbyteArray readBufferJava, jint bytestoread, jint timeoutMsecs)
jbyte* readBuffer = NULL;
try
readBuffer = pEnv->GetByteArrayElements(readBufferJava, NULL);
if (readBuffer == NULL)
throw std::bad_alloc();
int retval = XPNP_readBytes ((XPNP_PipeHandle)pipeHandle, (char*)readBuffer, bytestoread, timeoutMsecs);
std::cout<<"this is what I read: " << readBuffer << "\n";
std::flush(std::cout);
return (retval <= 0) ? 0 : retval;
catch (std::exception& except)
// setErrorInfo(except.what());
return 0;
此方法打印从调用XPNP_readBytes
读取的readBuffer
的正确文本,但将全零数组传递给Java!知道为什么会这样吗?我在传递指针或将其转换为 Java 时做错了吗?
这里是 Java 文件中原生 C++ 方法的声明。
private static native boolean readBytes(long pipeHandle, byte[] buffer, int bytesToRead, int timeoutMsecs);
这是我调用本机方法的地方。
boolean b = readBytes(namedPipeHandle, buffer, bytesToRead, timeoutMsecs);
String a = new String(buffer);
我在调用后读到的buffer
全为 0,尽管它在本机代码中打印了正确的文本!
【问题讨论】:
我会考虑使用直接的 ByteBuffer,因为它将地址保存到本机内存块。这避免了将数据复制到 byte[] 的需要,并且如果您需要读取更长的类型,例如int
或 double
,效率会更高
哦,我在这里使用的所有byte[]
实际上都是ByteBuffer
s。我刚刚做了一个toArray()
。为简单起见,我只是在帖子中写了byte[]
。无论如何感谢您的提示。
基本上((DirectBuffer) byteBuffer).address()
是你可以使用的void *
的地址。
如果它们是直接缓冲区,请参阅***.com/questions/8000548/…
这个问题及其 cmets 令人困惑。问题并没有简化为最简单的版本。 “我在这里使用的所有byte[]
实际上都是ByteBuffer
s”......“如果它们是直接缓冲区,那么......”......“不。它们是字节数组。”它是哪一个?你说他们是ByteBuffer
然后你说他们不是。我来到这里是因为问题标题表明这个问题是关于 ByteBuffer
,我正在查找文档,但问题似乎根本不是关于 ByteBuffer
,尽管标题说是。
【参考方案1】:
查找ReleaseByteArrayElements
。
【讨论】:
我从本机代码返回 Java 后立即收到此错误。也许是因为释放了内存?我不知道我在这里做什么。java(3440,0x1135d4000) malloc: *** error for object 0x7fdf6952d7f8: incorrect checksum for freed object - object was probably modified after being freed. *** set a breakpoint in malloc_error_break to debug
有时它会给出不同的错误。我得到这两个错误中的任何一个。很随意! Invalid memory access of location 0x0 rip=0x1025fd6f7
听起来你在数组边界之外写。
你的发布调用是什么样的?请注意,它释放的是 Java 数组内容的副本,而不是 Java 数组本身。
我认为您在数组中写入的字节数超出了容量。您可以使用 GetArrayLength 找出它有多大。或者以其他方式破坏内存。以上是关于jbyte* 作为 JNI 中本机 C++ 方法的 ByteBuffer的主要内容,如果未能解决你的问题,请参考以下文章
Java JNI:如何从 C++ 的本机方法设置 Java 类的 String [] 字段
JNI - 在本机 cpp 回调函数中使用 RxJava 的奇怪行为