开发者

COM - pass as input a fixed size array (size known at design time)

I have a com method where I want to pass information about 7 days of the week encoded in an unsigned开发者_开发问答 long (to represent "selected" hours of the day in the week)

[id(5)]          HRESULT GetSchedule([out, retval] SAFEARRAY(unsigned long)* days);
[id(6)]          HRESULT SetSchedule([in] SAFEARRAY(unsigned long) days);

This is one way to do this but it would not be obvious for the COM client that it has to pass an array of 7 elements, where each element is a day (let alone that ordering could be with first day Monday or Sunday, and is not explicit in the interface).

  • Is there a way to make the size of the input array explicit ?

I know it could still be better to split this in 7 different methods for every day, also


For Dispatch-compatible automation clients, where you have to use use SAFEARRAY's, this is not possible. SAFEARRAY knows its own size, an can be marshalled safely.

The best you can do in case of error is to return E_INVALIDARG and set an IErrorInfo describing the issue. Also, mention in your documentation.

For IUnknown-Binding you could use raw pointers with a size_is declaration for the intreface, but I doubt that owuld improve things.

edit

I know it could still be better to split this in 7 different methods for every day, also

Not necessarily, that would be painful to call in some circumstances.

There is a race condition with other clients trying to change a single value, you may need to take provisions for that.


You could also set it up as an indexed property (i.e. a propget / propput method that takes an addiitonal "weekday" parameter). Again, you would have to validate that the weekday parameter is in the valid range.

This would be a bit more obvious as interface, IMO, but if the object could be remote, a method to set all weekdays at once with a single server roundtrip is always welcome.


edit The MSDN page even recommends to use the fixed size for arrays, like this:

// MIDL:
HRESULT SetWeekdayNames([in] BSTR valNames[8]);

instead of the size_is variant:

HRESULT SetWeekdayNames([in, size_is(8)] BSTR * valNames);

The respective C++ declaration would probably be

HRESULT SetWeekdayNames(BSTR * valNames);

in both cases.


You should add a size parameter and return an error if you don't get the number you're expecting. E_INVALIDARG should send the caller looking for the documentation.

If you were marshalling, I suspect you can use a constant for size_is or length_is, but that's sort of not the situation here.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜