Friday, February 9, 2007

Passing Structs from COM to .NET

The easiest way of passing structs built out of primative data types from COM to .NET is to define the struct in your COM IDL file and use that struct in your COM code. Then expose a COM interface method to retrieve that struct and return it using standard COM rules. For example:

In your IDL define a struct like this:

typedef struct tagTeamInfo
{
long TeamId;
BSTR TeamName;
} TEAMINFO;
...
[id(6), helpstring("method GetTeamInfo")] HRESULT GetTeamInfo([in] LONG index, [out,retval] TEAMINFO* pTeamInfo);


Then, in your COM code, use the TEAMINFO struct as normal.

TEAMINFO ti;
ti.TeamId = gd->mObject;
ti.TeamName = StringToBSTR(gd->mName); //NOTE: See BSTR and .NET FAQ entry

In your implementation of the GetTeamInfo interface:

STDMETHODIMP CCollector::GetTeamInfo(LONG index, TEAMINFO* pTeamInfo)
{
const TEAMINFO& ti = mCurrentSession.GetTeamInfo(index);
pTeamInfo->TeamId = ti.TeamId;
pTeamInfo->TeamName = SysAllocString( ti.TeamName );
return S_OK;
}

Note that we allocate a new BSTR to place in the out TEAMINFO that was passed in. The caller is responsible for freeing that BSTR.

The cool part about all of this is that you can now pass a struct from COM to .NET and all of the memory allocations and such are taken care of for you (even the freeing of the BSTR!)

No comments: