DirectX9 CreateDevice 在 C 中失败,但在 C++ 中成功
Posted
技术标签:
【中文标题】DirectX9 CreateDevice 在 C 中失败,但在 C++ 中成功【英文标题】:DirectX9 CreateDevice fails in C, but succeds in C++ 【发布时间】:2020-12-11 15:22:40 【问题描述】:我在 C 中创建了一个 d3d9 应用程序,但是当尝试创建一个设备对象时,它在 C 中失败,但它在 C++ 中的对应项可以正常工作并返回 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 等效项是 memset
它的全零字节。试试看。
使用D3DPRESENT_PARAMETERS d3dpParams = 0;
所以我的猜测是正确的,确实有效,我不知道 会将内存归零。
【参考方案1】:
普通 C 结构的 =
初始化只会将内存归零。
Microsoft 在https://docs.microsoft.com/en-us/windows/win32/direct3d9/creating-a-device 的示例为此推荐ZeroMemory
:
D3DPRESENT_PARAMETERS d3dpp;
ZeroMemory( &d3dpp, sizeof(d3dpp) );
【讨论】:
【参考方案2】:C
版本不起作用的根本原因是:
D3DPRESENT_PARAMETERS d3dpParams;
创建一个名为d3dpParams
的未初始化变量。由于它是未初始化的,因此各个成员设置为的任何垃圾数据都将被CreateDevice
函数读取,从而导致不稳定的行为。你在 C++ 中也会遇到同样的问题,所以这并不是真正的 C 与 C++ 的问题。
由于问题是初始化问题之一,因此 C++ 代码通过使用 语法将结构中的所有元素设置为
0
来进行初始化。
由于C
没有这样的语法来初始化一个变量,你需要将所有成员设置为0
。函数ZeroMemory
、memset
和类似的C
函数可用于执行此操作。
ZeroMemory(&d3dpParams, sizeof(d3dpParams));
【讨论】:
【参考方案3】:C++ 中的零初始化器是:
D3DPRESENT_PARAMETERS d3dpParams = ;
C 中的等价初始化器是:
D3DPRESENT_PARAMETERS d3dpParams = 0;
您不必致电ZeroMemory
或memset
。请注意,对于符合标准的 C 编译器,C++ 版本将生成编译器警告,因为 C 中不允许使用空的初始值设定项。这就是需要“0”的原因。
【讨论】:
以上是关于DirectX9 CreateDevice 在 C 中失败,但在 C++ 中成功的主要内容,如果未能解决你的问题,请参考以下文章
来自全窗口游戏的 C++ DirectX CreateDevice
D3D->CreateDevice() 在注入的 DLL 中失败
使用 org.bluez.Adapter.CreateDevice 连接到 BT LE 设备失败并出现 org.bluez.Error.Failed:操作取消错误