// IDL
HRESULT GetData ([out] int* pCount,
[out, size_is (,*pCount)] unsigned char** ppBuffer);
// Caller
int nCount;
unsigned char* pBuffer;
HRESULT hr = pInterface->GetData (&nCount, &pBuffer);
if (SUCCEEDED (hr)) {
// pBuffer points to data and nCount holds length
•
•
•
CoTaskMemFree (pBuffer); // Important!
}
// Callee
int nSize = 1024;
*ppBuffer = (unsigned char*) CoTaskMemAlloc (nSize);
if (*ppBuffer == NULL)
return E_OUTOFMEMORY;
// Copy nSize bytes to the address in *ppBuffer
*pCount = nSize; // Return count to caller
return S_OK;
Figure 2 Rewriting GetText
// IDL
HRESULT GetText ([out, string] wchar_t** ppBuffer);
// Caller
wchar_t* pBuffer;
HRESULT hr = pInterface->GetText (&pBuffer);
if (SUCCEEDED (hr)) {
// pBuffer now holds a valid string pointer
•
•
•
CoTaskMemFree (pBuffer);
}
// Callee
wchar_t* pText = L"Hello, world";
*ppBuffer = (wchar_t*) CoTaskMemAlloc ((wcslen (pText) + 1) * 2);
if (*ppBuffer == NULL)
return E_OUTOFMEMORY;
wcscpy (*ppBuffer, pText);
return S_OK;
Figure 3 GetLine
// Caller
LINE line;
HRESULT hr = pInterface->GetLine (&line);
if (SUCCEEDED (hr)) {
int x1 = line.pFrom->x;
int y1 = line.pFrom->y;
int x2 = line.pTo->x;
int y2 = line.pTo->y;
CoTaskMemFree (line.pFrom);
CoTaskMemFree (line.pTo);
}
// Callee
POINT* pFrom = (POINT*) CoTaskMemAlloc (sizeof (POINT));
if (pFrom == NULL)
return E_OUTOFMEMORY;
POINT* pTo = (POINT*) CoTaskMemAlloc (sizeof (POINT));
if (pTo == NULL) {
CoTaskMemFree (pFrom);
return E_OUTOFMEMORY;
}
pFrom->x = 0;
pFrom->y = 0;
pTo->x = 100;
pTo->y = 50;
pLine->pFrom = pFrom;
pLine->pTo = pTo;
return S_OK;
Figure 4 Passing a Linked List
// IDL
typedef struct tagITEM {
int nVal;
struct tagITEM* pNext;
} ITEM;
HRESULT GetList ([out] ITEM** ppList);
// Caller
ITEM* pItem;
HRESULT hr = pInterface->GetList (&pItem);
if (SUCCEEDED (hr)) {
while (pItem != NULL) {
•
•
•
ITEM* pNext = pItem->pNext;
CoTaskMemFree (pItem);
pItem = pNext;
}
}
// Callee
ITEM* pItem1 = (ITEM*) CoTaskMemAlloc (sizeof (ITEM));
if (pItem1 == NULL)
return E_OUTOFMEMORY;
ITEM* pItem2 = (ITEM*) CoTaskMemAlloc (sizeof (ITEM));
if (pItem2 == NULL) {
CoTaskMemFree (pItem1);
return E_OUTOFMEMORY;
}
ITEM* pItem3 = (ITEM*) CoTaskMemAlloc (sizeof (ITEM));
if (pItem3 == NULL) {
CoTaskMemFree (pItem1);
CoTaskMemFree (pItem2);
return E_OUTOFMEMORY;
}
pItem1->nVal = 1;
pItem1->pNext = pItem2;
pItem2->nVal = 2;
pItem2->pNext = pItem3;
pItem3->nVal = 3;
pItem3->pNext = NULL;
*ppList = pItem1;
return S_OK;