2012-12-04 42 views

回答

5

你的代碼是正確的 - 的*bufferIBufferByteAccess接口上的引用計數由呼叫遞增爲QueryInterface,你必須調用Release一次釋放該參考。

但是,如果你使用ComPtr<T>,這變得簡單多了 - 與ComPtr<T>,你不能調用任何IUnknownAddRefReleaseQueryInterface)的三名成員;它阻止你打電話給他們。相反,它以這種方式封裝對這些成員函數的調用,這使得難以理解。下面是如何做到這一點看一個例子:

// Get the buffer from the WriteableBitmap: 
IBuffer^ buffer = bitmap->PixelBuffer; 

// Convert from C++/CX to the ABI IInspectable*: 
ComPtr<IInspectable> bufferInspectable(AsInspectable(buffer)); 

// Get the IBufferByteAccess interface: 
ComPtr<IBufferByteAccess> bufferBytes; 
ThrowIfFailed(bufferInspectable.As(&bufferBytes)); 

// Use it: 
byte* pixels(nullptr); 
ThrowIfFailed(bufferBytes->Buffer(&pixels)); 

bufferInspectable.As(&bufferBytes)調用執行安全QueryInterface:它的bufferBytes類型計算IID,執行QueryInterface,重視所產生的指針bufferBytes。當bufferBytes超出範圍時,它將自動呼叫Release。代碼與您的代碼具有相同的效果,但沒有容易出錯的顯式資源管理。

的示例使用以下兩種實用程序,這有助於保持代碼的清潔:

auto AsInspectable(Object^ const object) -> Microsoft::WRL::ComPtr<IInspectable> 
{ 
    return reinterpret_cast<IInspectable*>(object); 
} 

auto ThrowIfFailed(HRESULT const hr) -> void 
{ 
    if (FAILED(hr)) 
     throw Platform::Exception::CreateException(hr); 
} 

細心的讀者會發現,因爲這個代碼對IInspectable*一個ComPtr我們從buffer得到,這與原始代碼相比,代碼實際上執行額外的AddRef/Release。我認爲這種影響性能的可能性很小,最好從易於驗證爲正確的代碼開始,然後在理解了熱點後優化性能。

+0

謝謝!這有效,它非常有啓發性! –

0

這是我試過到目前爲止:

// Get the buffer from the WriteableBitmap 
IBuffer^ buffer = bitmap->PixelBuffer; 

// Get access to the base COM interface of the buffer (IUnknown) 
IUnknown* pUnk = reinterpret_cast<IUnknown*>(buffer); 

// Use IUnknown to get the IBufferByteAccess interface of the buffer to get access to the bytes 
// This requires #include <Robuffer.h> 
IBufferByteAccess* pBufferByteAccess = nullptr; 
HRESULT hr = pUnk->QueryInterface(IID_PPV_ARGS(&pBufferByteAccess)); 

if (FAILED(hr)) 
{ 
    throw Platform::Exception::CreateException(hr); 
} 

// Get the pointer to the bytes of the buffer 
byte *pixels = nullptr; 
pBufferByteAccess->Buffer(&pixels); 

// *** Do the work on the bytes here *** 

// Release reference to IBufferByteAccess created by QueryInterface. 
// Perhaps this might be done before doing more work with the pixels buffer, 
// but it's possible that without it - the buffer might get released or moved 
// by the time you are done using it. 
pBufferByteAccess->Release(); 
+0

您應該使用'ComPtr '。 ComPtr會在超出範圍時自動調用Release。否則,這看起來是正確的。使用IBufferByteAccess是Marian Luparu今年在他的// Build/talk中演示的例子之一:http://channel9.msdn.com/Events/Build/2012/3-010。 –