![](/img/trans.png)
[英]Why does gcc generate a memmove instead of a memcpy for copying a std::vector<>?
[英]why does memcpy copy only the first element of std::vector?
我正在嘗試將 DirectX::XMMATRIX 元素的向量復制到 Direct3D 頂點着色器常量緩沖區中,但它只復制第一個元素(即 4x4 浮點矩陣,即 64 字節),導致異常(它需要 3 個元素, 共 192 字節,向量有)
這是一個示例代碼:
template<typename C>
void Update(const std::vector<C>* cbuf)
{
D3D11_MAPPED_SUBRESOURCE msr = {};
GetContext()->Map(m_pConstBuffer.Get(), 0u, D3D11_MAP_WRITE_DISCARD, 0u, &msr);
memcpy(msr.pData, &cbuf[0], sizeof(C) * cbuf->size());
GetContext()->Unmap(m_pConstBuffer.Get(), 0u);
}
我還嘗試了 memcpy(msr.pData, cbuf->data(), sizeof(C) * cbuf->size()) ,並特別說明要復制 192 個字節 - 是的 - sizeof(C) * cbuf-> size() 結果為 192 - 但它仍然復制第一個元素的 64 個字節
那么有什么問題呢? 向量不是連續的嗎?
我認為這里的問題是您將std::vector
作為指針傳遞,因此&cbuf[0]
並沒有按照您認為的那樣做。
你也可以讓它更通用一點:
template<typename T>
void Update(T const& cbuf)
{
auto context = GetContext();
auto cb = m_pConstBuffer.Get();
D3D11_MAPPED_SUBRESOURCE msr = {};
if (SUCCEEDED(context->Map(cb, 0u, D3D11_MAP_WRITE_DISCARD, 0u, &msr)))
{
memcpy(msr.pData,
cbuf.data(),
sizeof(typename T::value_type) * cbuf.size());
context->Unmap(cb, 0u);
}
}
您沒有顯示資源的創建,因此如果這不起作用,請嘗試查看。
您可能想看看DirectX Tool Kit for DX11 。 有一個類似於您正在做的
MapGuard
類,並且BufferHelpers.h
標頭也可能會給您一些想法。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.