NGWS SDK Documentation  

This is preliminary documentation and subject to change.
To comment on this topic, please send us email at ngwssdk@microsoft.com. Thanks!

Handling problem interfaces

While the runtime’s generic marshalers do a good job of handling most types defined within a type library. However, there are certain situations that may require custom marshaling.

Variable sized arrays

Variable sized arrays of occasionally passed through COM interfaces. In order to marshal the array from a managed space to unmanaged space the size of the array must be know. In IDL, the size is designated using the size_is or length_is attribute. For example:

[uuid(…)]
interface foo {
   HRESULT Bar(int cb, [size_is(cb)] char *buffer);
}

In this case, buffer points to an array of characters and the size of the array is defined by the cb argument. By knowing the size (cb) and type (char) of the array the marshaler can safely copy the data.

Unfortunately, the size information is not propagated to the type library by the MIDL compiler. That leaves the runtime’s generic marshaler with no information about how to marshal the array. Consequently there is no way to pass a variable sized array from unmanaged code into managed code using the standard wrappers generated by TlbImp. One alternative is to use the MarshalAs attribute to explicitly supply the array size of to provide a custom marshaler for the interface.

Passing arrays from managed to unmanaged code is not a problem. Since the size of the managed array can always be obtained by checking the Count property of the System.Array class. Managed types being exposed to COM should still pass the array size in a separate parameter so that the size can be obtained on the unmanaged code.

Void pointers

Void pointers present a similar problem. The runtimes generic marshaler has no information telling it how to marshaler the data. Therefore marshaling interfaces with void pointers requires a custom marshaler.

Success results

The generic marshalers automatically convert COM HRESULTs to NGWS runtime exceptions and vice versa. However, some COM methods return success HRESULTs that are not handled by the runtimes marshalers. A custom marshaler can be used to provide associate other semantic with COM success HRESULTs.

Bridging existing functionality

In some cases a custom marshaler is used even though the runtime generic marshaler may have worked just fine. Instead the custom marshaler is used to bridge the “old” technique to a “new” technique of doing something. Consider the IEnumVariant interface. In COM, the interface is used to enumerate over a collection of Variants. It this interface that Visual Basic uses to implement its for…each semantics.

In the new NGWS programming model, the IEnumerator interface provide similar semantics even though the interfaces are not exactly the same. To bridge the 2 programming models the runtime provides a built-in custom marshaler that converts the IEnumVariant interface to the IEnumerator interface and vice versa. As a result, NGWS runtime types that support IEnumVariant now appear to support the IEnumerator interface and NGWS runtime types that support IEnumerator now appear to support IEnumVariant. This makes it possible to use For…each over a managed object that support IEnumerator from Visual Basic 6.0.

Other built-in custom marshalers are provided for bridging ITypeInfo to System.Type and IExpando to IDispatchEx.