你不能傳遞一個空指針作爲參數(又稱爲頂級指針),因爲它們在默認情況下是[ref]
。
但是你可以傳遞一個空指針,或縮小,對於非頂級指針。
的IDL方法定義是這樣的:
HRESULT GetStuffAB([in] long countA,
[in] long countB,
[out, size_is(, *pItemsA)] long **pA,
[out, size_is(, *pItemsB)] long **pB,
[out] long *pItemsA,
[out] long *pItemsB);
C++實現:
HRESULT CMyClass::GetStuffAB(long countA,
long countB,
long **pA,
long **pB,
long *pItemsA,
long *pItemsB)
{
// COM stubs will check this for you
// However, you should (must?) manually check in same apartment calls
if (!pA) return E_POINTER;
if (!pB) return E_POINTER;
if (!pItemsA) return E_POINTER;
if (!pitemsB) return E_POINTER;
*pA = nullptr;
*pB = nullptr;
*pItemsA = 0L;
*pItemsB = 0L;
if (countA < 0) return E_INVALIDARG;
if (countB < 0) return E_INVALIDARG;
// Get amount of As into *pItemsA if countA > 0
// Get amount of Bs into *pItemsB if countB > 0
if (*pItemsA < 0) return E_FAIL;
if (*pItemsB < 0) return E_FAIL;
if (*pItemsA > 0)
{
*pA = CoTaskMemAlloc(sizeof(long) * *pItemsA);
if (!*pA) return E_OUTOFMEMORY;
}
if (*pItemsB > 0)
{
*pB = CoTaskMemAlloc(sizeof(long) * *pItemsB);
if (!*pB)
{
if (*pA)
{
// You should not assume the memory will be freed by the caller
// in such drastic situations, so free and clear *pA here before returning
CoTaskMemFree(*pA);
*pA = nullptr;
}
return E_OUTOFMEMORY;
}
}
// Get As into *pA and Bs into *pB
// Or just copy them if getting the amounts implied getting the items
// You could just as well always return S_OK
return (*pItemsA > 0 || *pItemsB > 0) ? S_OK : S_FALSE;
}
並沒有展示任何其他代碼,你必須實現自己獲得的A
S中的量和金額的B
s,和A
s和B
s自己。
如果你必須拿到物品後知道金額,以及你不使用RAII,你應該在返回前手動釋放這些資源。
作爲替代使用CoTaskMemAlloc
和CoTaskMemFree
,您可能需要使用ATL的CComHeapPtr
,它會自動釋放內存RAII風格,從而簡化你的代碼。只要確保在成功返回之前將Detach
撥入*pA
和*pB
即可。
我建議你定義了三種方法,一個是'了',一個是'B',一個用於'了'和'B',所以你不必砍自己的方式思考空指針。此外,'HRESULT GetStuffA([IN]長數,[OUT,size_is(* pItems)]長** pA的,[OUT]長* pItems);'可以請求的量,但實際上返回不同的量,通常等於或小於請求者,被調用者用'CoTaskMemAlloc'分配數組,調用者用'CoTaskMemFree'釋放它。 – acelent 2014-12-06 01:25:58