views:

71

answers:

3

With a COM interface method declared as this:

[ object,
  uuid(....),
]
interface IFoo : IUnknown 
{
  HRESULT Foo([in, out] CACLSID * items);
}

With regards to marshalling, is the server allowed to reallocate the counted array? (I think it is, but I am not sure anymore)

Its current implementation only replaces the existing ID's, but I'd like to implement a change (that would not break contract) that may return more items without introducing a new interface.

[edit] please note that CACLSID is already an array, containing a count and a pointer.

+1  A: 

I have not done COM for a very long time but is it even possible to allocate a new array? In that case should it not be CACLSID ** items ?

Jakob Christensen
yes, CACLSID = struct { unsigned long cElems; CLSID * pElems; } where pElems is allocated using CoAlloc. So not exactly "allocate a new array", but "resize the exisitng one - which is probably exactly why I am unsure.}
peterchen
I am pretty sure you are not allowed to resize it when your IDL looks as it does. You need to use so-called open arrays if you need to resize. Something along the lines of: HRESULT Foo([in] long cMax, [in, out] long *pcActual, [in, out, size_is(cMax), length_is(*pcActual)] CLSID *pElemn).
Jakob Christensen
As I said I have not been programming COM for a long time but I opened up my "Essential COM" by Don Box and found it :-)
Jakob Christensen
Shouldn't it depend on the attributes the CACLSID definition gets?e.g. [size_is(cElems)] CLSID * pElems
peterchen
I don't think you can do it using the CACLSID. Somehow you need to use length_is if the callee needs to resize the array.
Jakob Christensen
A: 

You should give the Count as the second parameter which indicates the space for so many number of elements, using this COM library marshals the elements

Vinay
A: 

First, if you want Foo to accept an in array, you should add a paramter that gives the count, e.g.:

HRESULT Foo([in] int cItems, [in, out, size_is(cItems)] CACLSID * items);

Warning: this code has not been compiled, just going off documentation.

Secondly, you cannot modify the extern behavior of this method without changing its declaration. To support resizing, you need to be able to reallocate the array and pass back its address. You can use a SAFEARRAY or declare cItems and items as pointers to the original type Foo takes, e.g.:

HRESULT FooMutate([in, out] int *cItems, [in, out, size_is(*cItems)] CACLSID **items);

Again, not compiled, so you will actually have to know what you're doing if you use this.

MSN