简而言之,在以下定义中:
HRESULT GetStuff([in] long count,
[out, size_is(count)] long * a,
[out, size_is(count)] long * b);
用count元素填充a和b,调用者将a和/或b设置为null是否合法?
我想允许调用者只查询一组结果,因此可以使用
调用该方法long only_a_s[10];
itf->GetStuff(10, a, 0);
我是否需要修改MIDL声明?我不知道指针/ pointer_default属性如何发挥作用。
注意:单独获取它们会产生开销,但是获取调用者不需要的值也是如此,因此单独的getter或总是必须得到两者都是低于标准的。我知道它适用于inproc / in-apartment调用,但MIDL生成的代理/存根是否能正确处理?
答案 0 :(得分:1)
您不能将空指针作为参数传递(a.k.a。顶级指针),因为默认情况下它们是[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
的数量和B
的数量,以及A
和B
s自己。
如果您必须让项目知道金额,并且您没有使用RAII,则应在返回之前手动释放这些资源。
作为使用CoTaskMemAlloc
和CoTaskMemFree
的替代方法,您可能希望使用ATL的CComHeapPtr
,它将自动释放内存RAII样式,从而简化您的代码。在成功返回之前,请确保将Detach
调用*pA
和*pB
。