First, here are the most common causes of COM interop errors:
The most common error when attempting to create a COM component is not having the component registered.
The most common error when attempting to use .NET objects from COM clients is failure to place an assembly in an appropriate place.
The following are rules and facts about COM interop:
Using COM+ components in ASP.NET may require security changes.
COM properties that have by-reference parameters are not always supported by C#.
When calling methods that have optional variant types, you must use Type.Missing, because C# does not support optional/default parameters.
For optional nonvariant parameters, you must pass a default value.
If you need to delete a COM object immediately, you can call Marshal.ReleaseComObject(InteropServices) several times while checking the return value until it is zero.
COM variants IUnknown* and IDispatch* always look like System.Object in managed code.
When using late binding, parameters are passed as variants. Therefore, you should use ParameterModifier when Type.InvokeMember is being used without metadata being present.
The void* type used to represent a pointer to anything is always converted to System.IntPtr.
Runtime Callable Wrapper (RCW) classes (classes imported as ClassNameClass ) can be reliably cast only to interfaces that they implement.
When casting an RCW to a coclass, you are casting the object to the default interface.
Name conflicts are resolved by prefixing member names with the interface names and an underscore.
You can always cast an RCW class to an interface to call any methods with their original names.
In version 1.0 of the common language runtime (CLR), the type library importer does not properly handle type libraries containing a class that lists a source interface defined in a separate type.
Never use Marshal.SizeOf to determine the "real size" of a managed type, because the results can be misleading.
You can use the sizeof operator on any type that is blittable or a value type.
| Caution |
People often confuse the built-in C# operator sizeof and the Marshal.SizeOf functionality. sizeof returns the managed size of the type in bytes. Marshal. SizeOf returns the unmanaged size of a type in bytes. |
The default importer behavior of struct** is to convert an IntPtr.
In managed code, you cannot invoke members that use by-value user-defined type (UDT) parameters directly on dispinterfaces.
Once a thread's apartment type is defined, you cannot change it in .NET.
An InvalidCastException caused by a QueryInterface failure can happen when you are casting an RCW to a COM interface.
When using .NET components as COM components, the InprocServer32 will always be set to mscoree.dll.
Arrays of arrays are not supported in .NET clients that will be used by COM components.
The default behavior for importing a SAFEARRAY varies depending on the tool used, Visual Studio or tlbimp.exe. If you use Visual Studio to import the executable, SAFEARRAY s become System.Array objects. This is also true when using the tlbimp.exe tool with the /sysarray switch.
The Interop Marshaler does not support fixed-length arrays with more than one dimension.