在 c11 中用 clang 编译的程序中调用 DX12 函数时出现问题

Problem calling DX12 functions in a program compiled with clang in c11

为了学习,我尝试在纯 c11 中使用 clang 正确调用 DirectX12 API。我设法编译了所有内容,但有时 vtable 指针似乎被损坏并更改了它们不应该指向的位置。

ID3D12DeviceVtbl* tbl; //tracking the vtable pointer for debugging purposes

D3D_FEATURE_LEVEL featureLevel = D3D_FEATURE_LEVEL_11_0;
if (D3D12CreateDevice(NULL, featureLevel, &IID_ID3D12Device, (void**)&g_pd3dDevice) != S_OK)
{
    return false;
}

{
    tbl = g_pd3dDevice->lpVtbl;

    D3D12_DESCRIPTOR_HEAP_DESC desc ;
    desc.Type = D3D12_DESCRIPTOR_HEAP_TYPE_RTV;
    desc.NumDescriptors = NUM_BACK_BUFFERS;
    desc.Flags = D3D12_DESCRIPTOR_HEAP_FLAG_NONE;
    desc.NodeMask = 1;

    // works fine
    if (g_pd3dDevice->lpVtbl->CreateDescriptorHeap(g_pd3dDevice,&desc, &IID_ID3D12DescriptorHeap, (void**)&g_pd3dRtvDescHeap) != S_OK)
        return false;

    // works fine
    SIZE_T rtvDescriptorSize = g_pd3dDevice->lpVtbl->GetDescriptorHandleIncrementSize(g_pd3dDevice,D3D12_DESCRIPTOR_HEAP_TYPE_RTV);

    // works fine
    D3D12_CPU_DESCRIPTOR_HANDLE rtvHandle = g_pd3dRtvDescHeap->lpVtbl->GetCPUDescriptorHandleForHeapStart(g_pd3dRtvDescHeap);

    // after the line above executes, g_pd3dDevice->lpVtbl now points to somewhere new and invalid
}

{
    D3D12_DESCRIPTOR_HEAP_DESC desc ;
    desc.Type = D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV;
    desc.NumDescriptors = 1;
    desc.Flags = D3D12_DESCRIPTOR_HEAP_FLAG_SHADER_VISIBLE;

    // g_pd3dDevice->lpVtbl can't find CreateDescriptorHeap
    if (g_pd3dDevice->lpVtbl->CreateDescriptorHeap(g_pd3dDevice,&desc, &IID_ID3D12DescriptorHeap, (void**)&g_pd3dSrvDescHeap) != S_OK)
    {
        return false;
    }

    // tbl->CreateDescriptorHeap is still a valid pointer however.
}

如评论中所述,在 D3D12_CPU_DESCRIPTOR_HANDLE rtvHandle = g_pd3dRtvDescHeap->lpVtbl->GetCPUDescriptorHandleForHeapStart(g_pd3dRtvDescHeap); 行之后,g_pd3dDevice->lpVtbl 指针更改并指向无效的某处,我不明白为什么。

我正在使用以下选项进行编译:

clang.exe -std=c11 -pedantic-errors -g -D CINTERFACE .\main.c

您遇到了 C 绑定中的一个已知错误...请参阅 ,其中解释了 GetCPUDescriptorHandleForHeapStart 的错误。

There were similar issues with the C-bindings with Direct3D9Ex. The basic issue is that almost all users use C++ for DirectX since it naturally maps to COM. The C bindings are mostly automatically generated; they are not well tested or maintained.