2015-10-23 90 views
2

我在使用新橋接JNI入口點的類中使用std::vector與新的C++庫。修改std :: vector的基礎數據結構不會改變其大小

因爲有很多JNI來電涉及jbyteArray的,我已經寫了簡單的轉換功能:

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,其長度(通過獲得0)將保持在0.你有任何想法如何使向量顯示正確的大小?我會注意到,這個功能被稱爲大量的次,所以性能相當重要。

回答

2

當然,矢量的大小不會增加。想想看。

您正在使用GetByteArrayRegion將數據直接複製到矢量的底層緩衝區。你如何期待它的'規模'成員改變。

爲了解決這個問題我會用它的fill constructor

std::vector<uint8_t> result(static_cast<unsigned int>(len), 0); 

設置爲我創建它的向量的大小這將創建矢量與元素的len個填充,每個第二副本參數在這種情況下是0.

現在矢量的大小是你想要的,所以使用GetByteArrayRegion將數據直接複製到它應該沒問題。

1
memcpy(temp, v.data(), v.size()); 

此行不會更改std :: vector的size屬性。 「

它只是 」返回指向作爲元素存儲的底層數組的指針,指針使得range [data(); data()+ size())總是一個有效範圍,即使容器是空的「。 http://en.cppreference.com/w/cpp/container/vector/data

相反,

result.reserve(static_cast<unsigned int>(len)); 

可改爲

result.resize(static_cast<unsigned int>(len)); 
+0

你不能'reinterpret_cast'std :: vector :: iterator'成jbyte *。這就是我使用'data()'的原因。 – Crossfire

+0

我在這個函數中返回一個'jbyteArray',這個向量不應該在這裏改變。 – Crossfire