作为一个简短的例子,我有C ++ JNI代码,它将获取某些文件的文件大小,我想将其传递回Java。
A)这是一种理智的方法吗?
B)有没有更好的方法来执行此操作而不是将数据转储到String?
C ++代码段:
JNIEXPORT jstring JNICALL Java_test_TestClass_getNumBytes(...) {
boost::uintmax_t numBytes = 0;
try {
numBytes = boost::filesystem::file_size(MY_GLOBAL_FILE_NAME);
} catch(const boost::filesystem::filesystem_error& e) {
return env->NewStringUTF("0");
}
return env->NewStringUTF(boost::lexical_cast<std::string>(numBytes));
}
Java代码段:
private native String getNumBytes();
public void doStuff() {
final String s = getNumBytes();
final BigInteger bi = new BigInteger(s);
final StringBuilder sb = new StringBuilder("Comparing: ");
sb.append(s).append(" to ").append(bi);
System.out.println("Values should look the same: " + sb.toString());
}
假设Java无法访问MY_GLOBAL_FILE_NAME。
答案 0 :(得分:0)
只需将boost::uintmax_t
投射到jlong
即可。可能的精度损失很可能仍然是一个理论问题。 Java中的任何I / O API都使用签名的long
。
如果您想为符号成为问题的大小做好准备,您仍然可以将值jlong
传递给Java代码并将其修复到Java端,因为溢出不会破坏信息和该标志为溢出提供了一个易于检查的指标。
代码可能如下所示:
// 2⁶⁴
private static BigInteger twoP64=BigInteger.ZERO.flipBit(64);
public static BigInteger getNumBytes()
{
long longValue=getNumByteNative();
BigInteger i=BigInteger.valueOf(longValue);
if(longValue<0) i=i.add(twoP64);
return i;
}
private native long getNumByteNative();
这比在原生方面构建BigInteger
容易得多。并且它允许您在Java方面有条件地进行,只要它适合long
并且仅在必要时使用BigInteger
(我猜不会)。