DirectX 9 CreateDevice 在 C 中失败,但在 C++ 中成功
DirectX9 CreateDevice fails in C, but succeds in C++
我在 C 中制作了一个 d3d9 应用程序,但是当尝试创建一个设备对象时,它在 C 中失败了,但是它在 C++ 中的对应物却可以正常工作并且 returns S_OK.
C:
isOk = pD3D->lpVtbl->CreateDevice(pD3D, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, d3dpParams.hDeviceWindow, D3DCREATE_SOFTWARE_VERTEXPROCESSING, &d3dpParams, &lpDevice);
C++:
isOk = pD3D->CreateDevice(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, d3dpParams.hDeviceWindow, D3DCREATE_SOFTWARE_VERTEXPROCESSING, &d3dpParams, &lpDevice);
我的猜测在于D3DPRESENT_PARAMETERS d3dpParams
在 C++ 中,它用 "= {}" 初始化:
D3DPRESENT_PARAMETERS d3dpParams = {};
d3dpParams.Windowed = false;
d3dpParams.SwapEffect = D3DSWAPEFFECT_DISCARD;
...
而在 C 中你只能写“;”:
D3DPRESENT_PARAMETERS d3dpParams;
d3dpParams.Windowed = false;
d3dpParams.SwapEffect = D3DSWAPEFFECT_DISCARD;
...
*pD3D 是由 Direct3DCreate9() 创建的 IDirect3D9*,如果我理解正确,它不会失败。
最初是用 gcc 完成的,但是 msvc 给出了完全相同的结果。
普通 C 结构的 ={}
初始化仅将内存清零。
Microsoft 在 https://docs.microsoft.com/en-us/windows/win32/direct3d9/creating-a-device 的示例为此建议 ZeroMemory
:
D3DPRESENT_PARAMETERS d3dpp;
ZeroMemory( &d3dpp, sizeof(d3dpp) );
C
版本不起作用的根本原因是:
D3DPRESENT_PARAMETERS d3dpParams;
创建一个名为 d3dpParams
的未初始化变量。由于它是未初始化的,因此 CreateDevice
函数正在读取各个成员设置的任何垃圾数据,从而导致不稳定的行为。你会在 C++ 中遇到同样的问题,所以这不是真正的 C 与 C++ 问题。
由于问题之一是初始化,C++ 代码通过使用 {}
语法将结构中的所有元素设置为 0
来进行初始化。
由于C
没有这样的语法来初始化一个变量,你需要将所有成员设置为0
。函数 ZeroMemory
、memset
和类似的 C
函数可用于执行此操作。
ZeroMemory(&d3dpParams, sizeof(d3dpParams));
C++ 中的零初始化器是:
D3DPRESENT_PARAMETERS d3dpParams = {};
C 中等效的初始值设定项是:
D3DPRESENT_PARAMETERS d3dpParams = {0};
您不必致电 ZeroMemory
或 memset
。请注意,使用符合标准的 C 编译器时,C++ 版本将生成编译器警告,因为 C 中不允许使用空的初始值设定项。这就是为什么需要“0”的原因。
我在 C 中制作了一个 d3d9 应用程序,但是当尝试创建一个设备对象时,它在 C 中失败了,但是它在 C++ 中的对应物却可以正常工作并且 returns S_OK.
C:
isOk = pD3D->lpVtbl->CreateDevice(pD3D, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, d3dpParams.hDeviceWindow, D3DCREATE_SOFTWARE_VERTEXPROCESSING, &d3dpParams, &lpDevice);
C++:
isOk = pD3D->CreateDevice(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, d3dpParams.hDeviceWindow, D3DCREATE_SOFTWARE_VERTEXPROCESSING, &d3dpParams, &lpDevice);
我的猜测在于D3DPRESENT_PARAMETERS d3dpParams 在 C++ 中,它用 "= {}" 初始化:
D3DPRESENT_PARAMETERS d3dpParams = {};
d3dpParams.Windowed = false;
d3dpParams.SwapEffect = D3DSWAPEFFECT_DISCARD;
...
而在 C 中你只能写“;”:
D3DPRESENT_PARAMETERS d3dpParams;
d3dpParams.Windowed = false;
d3dpParams.SwapEffect = D3DSWAPEFFECT_DISCARD;
...
*pD3D 是由 Direct3DCreate9() 创建的 IDirect3D9*,如果我理解正确,它不会失败。
最初是用 gcc 完成的,但是 msvc 给出了完全相同的结果。
普通 C 结构的 ={}
初始化仅将内存清零。
Microsoft 在 https://docs.microsoft.com/en-us/windows/win32/direct3d9/creating-a-device 的示例为此建议 ZeroMemory
:
D3DPRESENT_PARAMETERS d3dpp;
ZeroMemory( &d3dpp, sizeof(d3dpp) );
C
版本不起作用的根本原因是:
D3DPRESENT_PARAMETERS d3dpParams;
创建一个名为 d3dpParams
的未初始化变量。由于它是未初始化的,因此 CreateDevice
函数正在读取各个成员设置的任何垃圾数据,从而导致不稳定的行为。你会在 C++ 中遇到同样的问题,所以这不是真正的 C 与 C++ 问题。
由于问题之一是初始化,C++ 代码通过使用 {}
语法将结构中的所有元素设置为 0
来进行初始化。
由于C
没有这样的语法来初始化一个变量,你需要将所有成员设置为0
。函数 ZeroMemory
、memset
和类似的 C
函数可用于执行此操作。
ZeroMemory(&d3dpParams, sizeof(d3dpParams));
C++ 中的零初始化器是:
D3DPRESENT_PARAMETERS d3dpParams = {};
C 中等效的初始值设定项是:
D3DPRESENT_PARAMETERS d3dpParams = {0};
您不必致电 ZeroMemory
或 memset
。请注意,使用符合标准的 C 编译器时,C++ 版本将生成编译器警告,因为 C 中不允许使用空的初始值设定项。这就是为什么需要“0”的原因。