我必須將現有資料(unsigned char已知大小的記憶體區域)傳遞給期望的庫函式const std::vector<std::byte>&。有什么方法可以“愚弄”庫函式,使其相信它在對現有資料進行操作時收到了一個向量?
我有來自舊遺產的資料作為指標和大小,而不是作為
std::vector. 傳統 C 代碼通過 malloc() 分配記憶體并提供指標和大小。請不要建議觸摸遺留代碼 - 在這句話結束時,我將不再是公司的員工。我不想創建臨時向量和復制資料,因為記憶體吞吐量很大(> 5GB/秒)。
Placement new 創建向量 - 但第一個位元組用于向量資料本身。我不能在記憶體區域之前使用幾個位元組 - 遺留代碼沒有預料到(見上文 - 記憶體區域由 malloc() 分配)。
更改第三方庫是不可能的。它期望 const std::vectorstd::byte& - 不跨越迭代器等。
看起來我沒有辦法,只能使用臨時向量,但也許還有其他想法……我不在乎,但它是關于密集的視頻處理,并且會有很多資料要白白復制。
uj5u.com熱心網友回復:
有什么方法可以“愚弄”庫函式,使其相信它在對現有資料進行操作時收到了一個向量?
不。
潛在的選擇是:
- 首先將資料放入向量中。
- 或者將期望向量的函式更改為不期望向量。
- 或者創建一個向量并復制資料。
如果 1. 和 2. 對您來說不是有效的選項,那么無論您是否愿意,您都只能選擇 3.。
uj5u.com熱心網友回復:
是的,你可以這樣做。不是以一種很好的安全方式,但它肯定是可能的。
您需要做的就是創建一個std::vector與std::vector. 然后將它的內部指標設定為指向您的資料并將reinterpet_cast您的假指標vector指向std::vector.
除非您真的需要這樣做,否則我不會推薦它,因為任何時候您的編譯器更改其std::vectorABI(基本上是欄位布局)都會中斷。雖然公平地說,這幾天不太可能發生。
uj5u.com熱心網友回復:
問題是它std::vector不是像std::string_viewor的參考類std::span。std::vector擁有托管記憶體。它分配記憶體并釋放擁有的記憶體。它不是為獲取外部緩沖區和釋放托管緩沖區而設計的。
你可以做的是一個非常骯臟的黑客。您可以創建具有與a完全相同的布局的新結構,std::vector使用從外部 lib 獲得的內容分配資料和大小欄位,然后將此結構作為std::vector const&using傳遞reinterpret_cast。它可以作業,因為您的庫不會修改向量(我假設它們不會在const_cast上執行std::vector const&)。
缺點是代碼不可維護。std::vector如果更改布局,下一次 STL 更新可能會導致應用程式崩潰。
以下是偽代碼
struct FakeVector
{
std::byte* Data;
std::size Size;
std::size Capacity;
};
void onNewData(std::byte* ptr, size_t size)
{
auto vectorRef = FakeVector{ptr, size, size};
doSomething(*reinterpret_cast<std::vector<std::byte>*>(&vectorRef));
}
轉載請註明出處,本文鏈接:https://www.uj5u.com/shujuku/445350.html
上一篇:為什么這個回圈會運行?
