私はちょうどBug in VC++ 14.0 (2015) compiler?から、構造体のレイアウトがどのようにメモリに格納されるかについて仮定しないことを学んだことがあります。しかし、私が見た多くのコードでは、それがどのように一般的な方法であるのか分かりません。例えば、バルカンのグラフィックスAPIは、以下のん:(ホスト・メモリ内の)構造体の上にC++の構造体レイアウトについて、どのように仮定することはできませんか?
uboVS.model = ...
uboVS....
それからちょうどコピーへ:
は、構造体
struct {
glm::mat4 projection;
glm::mat4 model;
glm::vec4 lightPos;
} uboVS;
は、そのフィールドをいっぱいに定義しますmemcpy経由のデバイスメモリ:
uint8_t *pData;
vkMapMemory(device, memory, 0, sizeof(uboVS), 0, (void **)&pData);
memcpy(pData, &uboVS, sizeof(uboVS));
vkUnmapMemory(device, memory);
次にGPUには、その構造体に一致するUBOが定義されていますct:
layout (binding = 0) uniform UBO
{
mat4 projection;
mat4 model;
vec4 lightPos;
} ubo;
GPU側では、uboは常にuboVSと一致します。
これは未定義の動作と同じですか?そのコードは、uboVS構造体が定義どおりにレイアウトされるか、または両側(コンパイルされたC++コードとコンパイルされたSPIR-Vシェーダ)が基本的に同じ構造体レイアウトを生成するかどうかに依存しませんか? (https://www.securecoding.cert.org/confluence/display/c/EXP11-C.+Do+not+make+assumptions+regarding+the+layout+of+structures+with+bit-fieldsの最初の例に似ています)
この質問は、VulkanやグラフィックスAPIに固有のものではありません。私は正確に何が想定できるのでしょうか、構造体をメモリの塊として使用するのは好奇妙です。私は構造体のパッキングとアライメントを理解していますが、それ以上のことはありますか?
おかげ
コンパイルドメイン全体で構造体を使用しないでください。時にはしばらく時間がかかるかもしれませんが、習慣として実行すると、他のソリューションが一度書かれ、定期的なメンテナンスは必要ない場合、コードのメンテナンスを頻繁に行う必要があります。あなたの計画が雇用保障のためにこれを行うことになっているなら、それを試して、それがあなたのためにどのくらいうまくいくかを確かめることができます。 –
[この質問と回答]を見てください。(http://stackoverflow.com/questions/38428666/why-can-glbufferdata-buffer-structs-for-ubo-and-ssbo-when-c-does -not-specify-s/38429253#38429253) –
構造体レイアウトに関する仮定を避けるために、構造体(特に)に 'memcpy'を使わないでください。 –