views:

711

answers:

2

What interop signature would you use for the following COM method? I am interested particularly in the final two parameters, and whether to try to use MarshalAs with a SizeParamIndex or not.

HRESULT GetOutputSetting(
  DWORD    dwOutputNum,
  LPCWSTR  pszName,
  WMT_ATTR_DATATYPE*  pType,
  BYTE*    pValue,
  WORD*    pcbLength
);

Documentation states:

pValue [out] Pointer to a byte buffer containing the value. Pass NULL to retrieve the length of the buffer required.

pcbLength [in, out] On input, pointer to a variable containing the length of pValue. On output, the variable contains the number of bytes in pValue used.

+1  A: 

You could try the PInvoke Signature Toolkit. It's rather useful for getting marshaling right when performing platform interops. It quite possibly won't cover your particular problem, but you may find a comparable one that gives you the information you seek.

Jeff Yates
I have. Its a nice tool, but it doesn't know what to do with things like this. It assumes that pValue is a single byte.
Mark Heath
That's unfortunate.
Jeff Yates
It's forced to assume byte* because there is no other data. You can add SAL annotations to give it enough context to generate the appropriate invocation.
JaredPar
+1  A: 

I would use the SizeParamIndex, because your scenario is exactly the one this feature is for: To specify the length of a variable sized array.

So the last to parameters would be in C# signature:

byte[] pValue,
ref ushort pcbLength

The byte-Array is passed without ref, because the array corresponds to a pointer in native code. If you pass NULL (or null in C#) for pValue in order to retrieve the size of the buffer needed. That means also that the caller has to allocate the byte-Array. The parameter pcbLength is passed by ref, because it is used as an in/out-parameter.

EFrank
ref for pValue is incorrect. If you look at the native signature there is only a single level of indirection (one pointer). Having an array + ref = 2 levels of indirection.
JaredPar
You are right, JaredPar. Thanks! I've edited my original answer to incorporate your comment,
EFrank