【发布时间】: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[]实际上都是ByteBuffers。我刚刚做了一个toArray()。为简单起见,我只是在帖子中写了byte[]。无论如何感谢您的提示。 -
基本上
((DirectBuffer) byteBuffer).address()是你可以使用的void *的地址。 -
如果它们是直接缓冲区,请参阅stackoverflow.com/questions/8000548/…
-
这个问题及其 cmets 令人困惑。问题并没有简化为最简单的版本。 “我在这里使用的所有
byte[]实际上都是ByteBuffers”......“如果它们是直接缓冲区,那么......”......“不。它们是字节数组。”它是哪一个?你说他们是ByteBuffer然后你说他们不是。我来到这里是因为问题标题表明这个问题是关于ByteBuffer,我正在查找文档,但问题似乎根本不是关于ByteBuffer,尽管标题说是。
标签: java c++ macos java-native-interface bytebuffer