我正尝试整理我们在各个项目中散布着的COM互操作定义,并将它们收集到一个单一的、确定无误的位置,以便整个开发团队可以从中受益。这一努力的一部分涉及清理多年积累的定义。
其中一些是从其他源代码借用来的,有些是直接从pinvoke.net复制而来的,还有一些看起来是直接从SDK头文件翻译过来的。我注意到的一件事是,使用各种封送属性的时机没有一致性,(即使在pinvoke.net的示例中也很随意)。问题的一部分在于,我不认为任何人(包括我自己)完全理解何时需要或不需要使用各种属性,或者它们实际上做了什么。到目前为止,正确地处理它们似乎是猜测和随机更改的组合,直到COM异常停止出现,但我更希望翻译是正确的,因为有人真正查看并声明了它们。
因此,我从[In]
和[Out]
开始。我知道这两个属性的概念是什么:它们通知封送程序数据必须走的方向。例如,我假设封送程序不会将[In]
数据复制回调用者,或知道需要在调用方释放[Out]
数据等。我不知道的是:
- 什么时候必须使用这些属性?也就是说,默认的封送行为何时是错误的,以至于这些属性可以使其正确?
- 什么时候使用这些属性是安全的?也就是说,指定应该已经是默认行为的内容会改变封送程序的工作方式吗?
- 使用这些属性什么时候是危险的?我假设明确标记输出参数
[In]
是不好的,但标记输入参数[In, Out]
实际上会破坏什么吗?
因此,考虑到一个假设的COM接口方法,其IDL代码如下:
HRESULT Foo(
[in] ULONG a,
[out] ULONG * b
[in, out] ULONG * c);
以下是可能的翻译:
void Foo(
uint cb,
out uint b,
ref uint c);
void Foo(
uint cb,
[Out] out uint b,
[In, Out] ref uint c);
void Foo(
[In] uint cb,
[Out] out uint b,
[In, Out] ref uint c);
这三者之间是否存在功能上的差异?除了技术正确性以外,它们中有哪一个被认为比其他人更好?