Je semble avoir trébuché sur un problème concernant la programmation de DirectX 12.0 et aucune recherche jusqu'ici n'a offert un aperçu du problème. Par conséquent, j'ai été laissé pour localiser le problème moi-même, sauf qu'il ne semble pas encore être une solution tangible.GetCPUDescriptorHandleForHeapStart corruption de la pile
Pour vous informer, je suis programmation en utilisant C (non C++) et, comme il ressort, les fichiers d'en-tête DirectX 12 fourni faire support C, aux côtés de C++, bien que le problème que je l'ai rencontré est étrange en ce sens qu'il semble mal conçu pour C, probablement en raison du fait que peu de gens programment des applications complexes (en particulier orientées objet) dans cette langue.
Ceci est mon problème: j'ai ici dans ma procédure D3D12 dispositif-initialisation du bloc de code suivant:
/* Get a handle to the memory location in the render target
view heap to identify where the render target views will be
located for the two back buffers */
hRTV = pThis->pRTVHeap->lpVtbl->GetCPUDescriptorHandleForHeapStart(pThis->pRTVHeap);
Où HRTV signifie ' poignée à Render Target Voir' (D3D12_CPU_DESCRIPTOR_HANDLE) et pRTVHeap signifie ' Pointeur à Render Target View Tas' (ID3D12DescriptorHeap).
est ici l'équivalent du C - ceci fonctionne très bien:
/* Get a handle to the memory location in the render target
view heap to identify where the render target views will be
located for the two back buffers */
hRTV = this->pRTVHeap->GetCPUDescriptorHandleForHeapStart();
Il n'y a pas d'erreur de compilation actuelle, mais lors de l'exécution, appelant cette méthode (GetCPUDescriptorHandleForHeapStart) en C déclenche une corruption de pile (ESP se dérégler par 4 octets).
j'ai examiné le démontage du procédé et pris note du RET (retour) instruction:
50290030 mov edi,edi
50290032 push ebp
50290033 mov ebp,esp
50290035 mov ecx,dword ptr [ebp+8]
50290038 mov eax,dword ptr [ecx+2Ch]
5029003B cmp dword ptr [eax],2
5029003E jne 5029004A
50290040 mov eax,dword ptr [ebp+0Ch]
50290043 mov ecx,dword ptr [ecx+28h]
50290046 mov dword ptr [eax],ecx
50290048 jmp 50290055
5029004A push dword ptr [ebp+0Ch]
5029004D call 5029005E
50290052 mov eax,dword ptr [ebp+0Ch]
50290055 pop ebp
50290056 ret 8
Pour ceux qui sont familiers avec l'assemblage, ou autrement la convention d'appel __stdcall des objets COM (Object Model Component) , le pointeur 'this', transmis sur la pile, est le premier paramètre (et, dans ce cas, le seul paramètre) de la méthode, de sorte que l'objet COM peut accéder à ses propres données.
L'extrait de code suivant (montré également à la fin de l'extrait de code ci-dessus) appelle ma confusion, et à juste titre lorsque le moteur d'exécution renvoie une erreur « désaligné ESP »:
ret 8
Un seul paramètre est d'être passé dans ce cas, qui est le pointeur "this". La taille d'un pointeur (sur un système 32 bits - mon architecture cible pour le moment est x86) est de 4 octets (32 bits), alors pourquoi l'appelé nettoie-t-il 8 octets sur la pile?
Ai-je raison de dire que c'est un bug? Microsoft a-t-il besoin d'être informé de ce problème? Ai-je tort? Est-ce une erreur stupide de ma part?
Merci pour votre temps et j'espère que quelqu'un avec plus de connaissances que moi peut m'éclairer sur le problème, mais ne suggère pas que la solution serait d'écrire en C++ au lieu de C. qu'il ne devrait pas être nécessaire et personnellement, je pense, dans mon cas, que ce serait une approche paresseuse, surtout quand je trouve que C permet un contrôle plus programmatique et (dans mon cas ici) plus d'efficacité.
La même chose se produit-elle, par ex. 'GetResourceAllocationInfo' et d'autres méthodes struct-return? Dans tous les cas, vous devez modifier votre réponse et l'accepter (peut-être même obtenir le badge [self-learner] (http://stackoverflow.com/help/badges/14/self-learner) pour aider à augmenter visibilité pour [les gens du futur] (https://xkcd.com/979/). – MooseBoys
Je vais enquêter. Je ne m'attendais pas à une réponse - excusez ma réponse tardive. Après avoir signalé le problème à Microsoft, j'ai reçu un accusé de réception. Je n'ai aucune idée si quelque chose est fait, ou si mon problème est considéré. Il devrait être facile à corriger car, après tout, c'est seulement le fichier d'en-tête qui doit être modifié et non l'API elle-même. Mais je vais enquêter et revenir avec mes découvertes. Je ne peux rien garantir, je suis toujours un débutant DirectX-12. –