修改 std::vector 的基础数据结构不会改变其大小
Modifying underlying data structure of std::vector doesn't change its size
我在 class 桥接 JNI 入口点和新的 C++ 库中使用 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;
}
问题
如果我通过 data()
方法修改 vector
,它的长度(通过 size()
获得)将保持为 0。你有什么想法如何让矢量显示尺寸正确吗?我会注意到,这个函数被调用了很多次,所以性能非常重要。
memcpy(temp, v.data(), v.size());
此行不会更改 std::vector 的大小 属性。
只是
"Returns pointer to the underlying array serving as element storage. The pointer is such that range [data(); data() + size()) is always a valid range, even if the container is empty."
http://en.cppreference.com/w/cpp/container/vector/data
相反,
result.reserve(static_cast<unsigned int>(len));
可以改成
result.resize(static_cast<unsigned int>(len));
向量的大小当然不会增加。想想看。
您正在使用 GetByteArrayRegion 将数据直接复制到矢量的底层缓冲区。您希望它的 'size' 成员如何改变。
为了解决这个问题,我会在创建矢量时使用它设置矢量的大小 fill constructor
std::vector<uint8_t> result(static_cast<unsigned int>(len), 0);
这将创建向量并用 len 个元素填充它,每个元素都是第二个参数的副本,在本例中为 0。
现在矢量的大小就是您想要的大小,因此使用 GetByteArrayRegion 将数据直接复制到其中应该没问题。
我在 class 桥接 JNI 入口点和新的 C++ 库中使用 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;
}
问题
如果我通过 data()
方法修改 vector
,它的长度(通过 size()
获得)将保持为 0。你有什么想法如何让矢量显示尺寸正确吗?我会注意到,这个函数被调用了很多次,所以性能非常重要。
memcpy(temp, v.data(), v.size());
此行不会更改 std::vector 的大小 属性。
只是 "Returns pointer to the underlying array serving as element storage. The pointer is such that range [data(); data() + size()) is always a valid range, even if the container is empty." http://en.cppreference.com/w/cpp/container/vector/data
相反,
result.reserve(static_cast<unsigned int>(len));
可以改成
result.resize(static_cast<unsigned int>(len));
向量的大小当然不会增加。想想看。
您正在使用 GetByteArrayRegion 将数据直接复制到矢量的底层缓冲区。您希望它的 'size' 成员如何改变。
为了解决这个问题,我会在创建矢量时使用它设置矢量的大小 fill constructor
std::vector<uint8_t> result(static_cast<unsigned int>(len), 0);
这将创建向量并用 len 个元素填充它,每个元素都是第二个参数的副本,在本例中为 0。
现在矢量的大小就是您想要的大小,因此使用 GetByteArrayRegion 将数据直接复制到其中应该没问题。