COM - 将固定大小的数组作为输入传递(大小在设计时已知)

发布于 2024-12-04 02:09:40 字数 415 浏览 1 评论 0原文

我有一个 com 方法,我想传递有关一周中 7 天的信息,这些信息以无符号长整数编码(以表示一周中一天中的“选定”时间),

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

这是执行此操作的一种方法,但对于COM 客户端必须传递一个包含 7 个元素的数组,其中每个元素代表一天(更不用说排序可能是周一或周日的第一天,并且在界面中不明确)。

  • 有没有办法使输入数组的大小明确?

我知道每天将其分成 7 种不同的方法可能会更好,也

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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

赠我空喜 2024-12-11 02:09:40

对于与 Dispatch 兼容的自动化客户端,您必须使用 SAFEARRAY,这是不可能的。 SAFEARRAY 知道自己的大小,可以安全地编组。

如果出现错误,您能做的最好的事情就是返回 E_INVALIDARG 并设置描述问题的 IErrorInfo。另外,请在您的文档中提及。

对于 IUnknown-Binding,您可以使用带有 size_is 声明的原始指针作为 intreface,但我怀疑这是否会有所改善。

编辑

我知道每天将其分成 7 种不同的方法可能会更好

一定,在某些情况下调用会很痛苦。

其他客户端试图更改单个值时存在竞争条件,您可能需要为此采取措施。


您还可以将其设置为索引属性(即采用附加“工作日”参数的 propget / propput 方法)。同样,您必须验证工作日参数是否在有效范围内。

在我看来,作为接口,这会更明显一些,但如果对象可以是远程的,那么通过单个服务器往返一次设置所有工作日的方法总是受欢迎的。


编辑 MSDN 页面 甚至建议对数组使用固定大小,如下所示:

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

而不是 size_is 变体:

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

相应的 C++ 声明可能

HRESULT SetWeekdayNames(BSTR * valNames);

在这两种情况下都是如此。

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.

两相知 2024-12-11 02:09:40

您应该添加一个大小参数,如果没有得到您期望的数字,则返回错误。 E_INVALIDARG 应该让调用者寻找文档。

如果您正在编组,我怀疑您可以使用 的常量size_islength_is,但这不是这里的情况。

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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文