我在使用新C ++库桥接JNI入口点的类中使用std::vector
。
由于有很多涉及jbyteArray
的JNI调用,我编写了简单的转换函数:
std::vector<uint8_t> Jni::Types::vectorForJarray(jbyteArray a) {
auto env = Jni::getEnv();
auto len = env->GetArrayLength(a);
std::vector<uint8_t> result;
result.reserve(static_cast<unsigned int>(len));
env->GetByteArrayRegion (a, 0, len, reinterpret_cast<jbyte*>(result.data()));
return result;
}
和
jbyteArray Jni::Types::JarrayForVector(std::vector<uint8_t> v) {
auto env = Jni::getEnv();
auto array = env->NewByteArray(v.size());
if (env->GetArrayLength(array) != v.size()) {
env->DeleteLocalRef(array);
array = env->NewByteArray(v.size());
}
void* temp = env->GetPrimitiveArrayCritical(array, 0);
memcpy(temp, v.data(), v.size());
env->ReleasePrimitiveArrayCritical(array, temp, 0);
return array;
}
问题
如果我通过vector
方法修改data()
,其长度(通过size()
获得)将保持为0.您是否有任何想法如何使向量显示正确的大小?我会注意到,这个函数被称为很多次,因此性能非常重要。
答案 0 :(得分:2)
当然,矢量的大小不会增加。想一想。
您正在使用GetByteArrayRegion将数据直接复制到矢量的底层缓冲区。你怎么期望它的'大小'成员改变。
要解决此问题,我会设置矢量的大小,因为我使用fill constructor
创建它std::vector<uint8_t> result(static_cast<unsigned int>(len), 0);
这将创建向量并用len个元素填充它,每个元素都是第二个参数的副本,在本例中为0。
现在,矢量的大小是你想要的,所以使用GetByteArrayRegion将数据直接复制到它中应该没问题。
答案 1 :(得分:1)
memcpy(temp, v.data(), v.size());
此行不会更改std :: vector的size属性。
只是 &#34;返回指向用作元素存储的基础数组的指针。指针是范围[data(); data()+ size())始终是有效范围,即使容器为空。&#34; http://en.cppreference.com/w/cpp/container/vector/data
相反,
result.reserve(static_cast<unsigned int>(len));
可以更改为
result.resize(static_cast<unsigned int>(len));