Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
123 views
in Technique[技术] by (71.8m points)

c# - When is it necessary/appropriate to use InAttribute and OutAttribute for COM Interop

I am trying to go through the mess of COM interop definitions we have scattered across various projects and collect them into a single, known-good location from which the whole dev team can benefit. Part of this effort involves cleaning up the definitions that have been accumulated over the years.

Some of these are borrowed from other source code, some were copied verbatim from pinvoke.net, and some look to be directly translated from the SDK headers. One thing I notice is that there is no consistency about when to use the various marshalling attributes, (even among the pinvoke.net examples this is pretty hit-or-miss). Part of the problem is, I don't think anyone here (myself included) fully understands when the various attributes are needed or not, or what they actually do. Up to this point, getting these right seems to be a combination of guesswork and random changes until the COMExceptions stop happening, but I'd much rather the translations be correct because someone actually looked at them and declared them so.

So, I'm starting with [In] and [Out]. I know what those two attributes do conceptually: they inform the marshaller which direction the data has to go. I assume the marshaller, for example, won't bother copying [In] data back to the caller, or knows that [Out] data might need to be freed on the callee side, etc. The things I don't know are:

  1. When is it necessary to use these attributes? That is, when is the default marshalling behavior wrong such that the attributes make it correct?
  2. When is it safe to use these attributes? That is, will specifying what should already be the default behavior change the way the marshaller works?
  3. When is it dangerous to use these attributes? I assume that explicitly marking an output parameter [In] is bad, but is marking an input parameter [In, Out] actually going to break anything?

So, given a hypothetical COM Interface method whose IDL looks like this:

HRESULT Foo(
    [in] ULONG a,
    [out] ULONG * b
    [in, out] ULONG * c);

I might see this translated as any of the following:

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);

Is there any functional difference between those three? Is any of them considered "better" than the others for reasons besides technical correctness?

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

No, it's not strictly necessary to apply any of these attributes in your own code. They're all optional, and automatically applied to your code depending on the type of the parameter.

Essentially, they have the following C# keyword equivalents:

  • You get [In] by default.
  • The ref keyword gets you [In, Out].
  • The out keyword gets you [Out].

All documented in a nice table here.

You only need to use them when you want to alter those implied semantics or change the default behavior of the marshaler. For example, you can mark a parameter declared ref with the [In] attribute only to suppress the "out" part of marshaling.

That said, I find myself using them because they're a very easy way of making code self-documenting.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...