0

私のシナリオは次のとおりです。

呼び出し元関数::

IDirect3DSurface9 * surf = null;
Func(&surf);
hr = surf->LockRect(, , );  // THROWS an EXCEPTION BCOZ "surf" is still null. Dont know why ??

CALLED 関数では:

Func(IDirect3DSurface9 **surfReceive)
{
   surfReceive= new IDirect3DSurface9*[10];
  IDirect3DSurface9* surfcreate = NULL;

        hr = xyz->CreateOffscreenPlainSurface(  width, 
                                                            height, 
                                                            formt, 
                                                            D3DPOOL_DEFAULT, 
                                                            &surfcreate, 
                                                            NULL);
        if (FAILED(hr)) 
            return hr;

        surfReceive[0] = surfcreate;
}

私の疑問は、(上記のコードで示したように) CALLER では、呼び出し元が戻った後でも surf がまだ null であるということです。そして、以下のようにサーフで LockRect() を呼び出すと例外がスローされます。

hr = surf->LockRect(, , );  

「CreateOffscreenPlainSurface()」呼び出しが成功を返し、「surfcreate」が正しい値を格納するため、surfReceive[0] も正しい値を格納することに注意することが重要です。しかし、CALLERでこれにアクセスする方法を間違えていると思います。

4

2 に答える 2

1

あなたのコードは悪い点と間違った点でいっぱいです。前述の問題に加えて、安全でない例外、DRY 違反、メモリ リークも見られます。問題は、正確には、ポインターと値の違いを認識していないことです。に割り当てるとsurfReceive、元の値が消去され、新しい値が返されることはありません。さらに、後で削除する楽しみがあります。

関数の呼び出し元が通常のポインターを期待しているポインターの配列へのポインターを返そうとするため、これは決して機能しないことがわかります。

クラスベースのコードを使用して、明確さ、安全性、およびパフォーマンスを一度に実現します。

struct COMDeleter {
    template<typename T> void operator()(T* p) {
        p->Release();
    }
};
void CheckD3DResult(HRESULT hr) {
#ifdef _DEBUG
    if (FAILED(hr)) {
        __debugbreak();
    }
#endif
}
std::unique_ptr<IDirect3DSurface9, COMDeleter> Func() {
    IDirect3DSurface9* temp = nullptr;
    CheckD3DResult(xyz->CreateOffscreenPlainSurface(
        width, 
        height, 
        formt, 
        D3DPOOL_DEFAULT, 
        &temp, 
        NULL));
    return std::unique_ptr<IDirect3DSurface9, COMDeleter>(temp);
}
std::unique_ptr<IDirect3DSurface9, COMDeleter> surf = Func();
CheckD3DResult(surf->LockRect(...));

このコードは例外を尊重し、メモリのクリーンアップを保証し、少なくとも DRY を尊重します。

于 2012-06-05T17:11:47.990 に答える
0

に何を期待しているのかはわかりませんFuncが、これは間違いなく機能しません。

すでに割り当てられている (スタック上にある) ポインターへのポインターを何にでも渡しFuncます。内部では、 (ヒープ上で)割り当てたばかりのアドレスに引数(すでに割り当てられているポインタへのポインタ)を再割り当てします。Func

surfReceiveへの呼び出しだけで、何も割り当てないでくださいCreateOffscreenPlainSurface。ポインターへのアクセスには、 を使用するだけ*surfReceiveです。

しかし、あなたは、私が理解できない理由で、10個のポインターの配列を何にでも割り当てます。

于 2012-06-05T17:12:17.320 に答える