In C++, either C casts or the C++ cast operators (static_cast
, const_cast
, reinterpret_cast
and dynamic_cast
) can be used for the purposes of casting parameters to Direct3D functions (and, indeed, most anywhere). There are subtle differences between the C and C++ casts, but not all of them are applicable here. For more information you could start with this StackOverflow question.
I prefer the C++ casts when writing C++ code because I feel they clarify my intent more, and are more restrictive in terms of potentially dangerous behavior (you cannot, for example, use a static_cast
to remove CV qualifiers but a C cast happily will do just about anything). What is more important is that you are consistent in your own usage throughout your own code.
Note that there is a big difference between casting a parameter to void *
and casting one to void **
. The latter type has an extra level of indirection and is thus a very different type from the former. Thus, while the style of cast you use is somewhat flexible the types you cast to aren't. Different D3D functions will expect casts to different types.
The origin of most of these castable parameters is in the fact that D3D uses COM technologies and uses output parameters to return pointers to interface objects. The specific type of interface isn't fixed at compile time, and so the API uses void **
to represent a generic output, but you generally want to work with known interfaces in your own code, and thus the cast:
// We want to get the swap chain buffer and do some stuff to it;
// specifically we want to manipulate it as a texture, so we declare
// a variable of the appropriate type (pointer-to-texture)
ID3D10Texture2D * texture;
// Get the first buffer of the swap chain. This is a good example of the
// "unknown interface" issue mentioned above. Here, we tell GetBuffer that
// we'd like to get the buffer as a texture via the second parameter. This
// allows the function to fail gracefully if the buffer does not support
// the ID3D10Texture2D interface.
//
// Since GetBuffer doesn't know the result type at compile time it's output
// parameter is a void **, but we know the result type and declared it above.
// That's why we need the cast to void **, which we do using a C++ cast here:
swapChain->GetBuffer(0, __uuidof(texture), reinterpret_cast<void**>(&texture));